In the 4.0.2a docs: http://docs.sencha.com/ext-js/4-0/#/...pp.Application
I see this:
Ext.application({
name: 'MyApp',
launch: function() {
Ext.create('Ext.container.Viewport', {
items: {
html: 'My App'
}
});
}
});
"This does several things. First it creates a global variable called 'MyApp' - all of your Application's classes (such as its Models, Views and Controllers) will reside under this single namespace, which drastically lowers the chances of colliding global variables."
When I run this code, I do not see a global variable called MyApp... does anybody else have this problem?
Here is my entire app (in a single HTML page):
<!DOCTYPE html>
<html>
<head>
<title>Testing ExtJS 4</title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="extjs/ext-all-debug-w-comments.js"></script>
<script type="text/javascript">
Ext.application({
name: 'MyApp',
launch: function() {
Ext.create('Ext.container.Viewport', {
items: {
html: 'My App'
}
});
}
});
Ext.onReady(function() {
alert(typeof MyApp);
});
</script>
</head>
<body></body>
</html>
it's not working because as the api states (guide/mvc application architecture):
"... All Ext JS 4 applications should only use a single global variable, with all of the application's classes nested inside it...".
If you try with this code:
Ext.application({
name: 'MyApp',
appFolder: '/app',
autoCreateViewport: true,
launch: function() {
console.log(MyApp);
}
});
you will see that the global variable exists. You don't need to access the application from any other place than the application itself
I get the same error, and here are what I found.
In index.html:
Ext.Loader.setConfig({enabled:true});
Ext.application({
name: 'MyApp',
controllers: ['Test'],
launch: function() {
Ext.create('Ext.container.Viewport', {
items: {
html: 'My App'
}
});
}
});
Ext.onReady(function() {
alert(typeof MyApp);
});
Create a small controller: app/controller/Test.js (/app has the same parent folder as /extjs)
Ext.define('MyApp.controller.Test', {
extend: 'Ext.app.Controller',
init: function() {
console.log('The controller was initialised');
}
});
When running, in Firebug you will see the MyApp global variable. However, a messagebox of 'undefined' still appeared for alert statement.
IMHO MyApp is an object to "maintains references to all of the models, views and controllers used by the app". Maybe extjs use some type of class "Dynamic loading"; so it will not create that global variable until there is something (controllers, views, models) to contain inside (I am not sure of this). In this case the variable must be created to contain the controller Test. However, I cannot explain the 'undefined' message for alert. Maybe at that time the Ext object is ready but "Dynamic loading" to create the viewport and the variable MyApp is not finished (not sure).
Hope this help.
Related
EDIT As far as I understood through further research AngularJS isn't capable of injecting that controller code the way I wanted it to do. Anyway, I'm still interested in why exactly doesn't it work and how should it be done.
I've been trying to create my own AngularJS + RequireJS project seed and I've run into issues with app modules loading (I see them in the network inspector) but never actually executing.
So I've stripped down the app to just the AngularJS library with basic dependencies handled through in RequireJS and I've noticed that the app loads all of the files and modules properly but the top level application module controller (and now the only module in the app itself) that I'm bootstrapping onto the document never executes. Using ng-inspector I've come to a conclusion that there's also no controller scope defined.
There are no errors whatsoever in the console and what I can confirm is that app bootstraps properly and loads all of the modules but the appController is never executed.
Here's the code of the appBootstrap.js:
//requirejs config
require.config({
baseUrl: '/',
paths: {
'lib' : 'scripts/lib/',
'angular' : 'vendor/angular/angular.min'
},
shim: {
'angular': {
exports: 'angular'
}
}
});
//the actual app bootstrapping
require(['lib/appVendorLibs'], function(){
require([
'lib/appModule'
], function(appModule) {
angular.bootstrap(document, [appModule.name]);
});
});
Here's the appVendorLibs.js:
define([
'angular'
], function() {});
And here's the barebones appModule.js that I've come up with in order to test the controller execution that fails:
define([
'angular',
'lib/appController'
], function(angular, appController) {
var app = angular.module('app', []);
app.controller('appController', appController);
return app;
});
Here's the appController.js:
define([], function() {
var appController = function($scope, $rootScope){
$rootScope.aTestVar = "OK";
$scope.testObject = {};
$scope.testObject.text = "OK";
console.log("OK");
};
return ['$scope', '$rootScope', appController];
});
That console.log() call is never occurs nor do those lines referencing the $rootScope and $scope do anything.
Also, I've got ng-bind in my index.html that should be displaying the testObject.text variable but that never happens.
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="/styles/styles.css"/>
<title>AngularJS Module Loading Seed</title>
<base href="/">
</head>
<body>
<!-- Main Content Container -->
<p ng-bind="testObject.text"></p>
<script src="/vendor/requirejs/require.js" data-main="/scripts/lib/appBootstrap.js"></script>
</body>
</html>
What could be the problem here?
I'm fairly new to Angular JS.
I was doing some practice demos with require JS along with angular routing using route provider in a well defined folder structure.
I tried searching for similar angular router problems but most do not have any folder structure, Their code was present in script tags.
I hope somebody has the patience to have a quick look and checkout why the route provider seems so non functional despite everything seeming to be done correct. :)
Anyway,
I have an index.html that simply loads the require JS with a source
Index.html
<!DOCTYPE html>
<html>
<head>
<title>MyApp</title>
<meta charset="utf-8"/>
<script data-main="assets/require/requireConfig" src="assets/vendor/require.js"></script>
<link rel="stylesheet" href="assets/css/site.css">
</head>
<body>
<ng-view></ng-view>
</body>
</html>
The Require JS source looks as follows where 'router' is the standard angular-router.
'myApp' would be the app I'm going to bootstrap.
The data source of Require JS
requirejs.config({
baseUrl: 'assets',
paths: {
'myApp': 'require/myApp',
'angular': 'vendor/angular',
'router': 'vendor/angular-route',
'domReady': 'vendor/dom-ready'
},
//Shim is also used to specify if one module must be loaded only after another
//angular does not support AMD out of the box, put it in a shim
shim: {
'angular': {
exports: 'angular'
},
'router': {
deps: ['angular'],
exports: 'router'
}
},
// kick start application
// The ./ represents the base URL given at the top
deps: ['./require/startup']
});
So Now I'm going to run the startup.js to bootstrap my app file
The following is how my startup.js looks
Angular Bootstrapping
define([
'require',
'angular',
'myApp'
], function (require, angular) {
'use strict';
require(['domReady!'], function (document) {
angular.bootstrap(document, ['myApp']);
});
});
And finally....
The Route Provider that is causing all the problems is defined in myApp.js
define(['angular','router'], function (angular) {
'use strict';
var myApp = angular.module('myApp', ["ngRoute"]);
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/login', {
templateUrl: '../../modules/login/login.html'
});
$routeProvider.when('/home', {
templateUrl: '../../modules/home/homepage.html'
});
}]);
});
Ok, So I run the application on an nginx server.
http://localhost/login
OR
http://localhost/home
does not direct me to the required pages I have specified in the templates.
However
If I specify a "$routeProvider.otherwise" it always redirects to it.
If I change $routeProvider.when("/login") to
$routeProvider.when("/"), The router opens up the login page but
complains there is no controller associated with the view specified.
(Hence my conclusion that the template URLs were pointing correctly)
Deciding to create a controller 'loginController' throws the error that the 'controller is not registered'. For which when I digged around that is due to bootstrapping. (Wha?. So whats good about requireJS? But I'll leave that question for another time)
So, why such weird behavior by the route provider?
I do not see it?
I've simplified this to its barebones - pulled out any properties that might be interfering (I can put em back in if you like) - even pointing it at local .json - and still getting no data in my grid.
I did see data in the sample that I dropped in, when it was pointing at the Northwind api, so I know I've got my i's crossed and t's dotted.
<div id="grid"></div>
This is in my controller:
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: 'Content/data/Listings.json'
}
},
height: 550,
columns: [{
field: "Id",
title: "Id",
width: 240
},{
field: "State",
title: "State",
width: 240
}]
});
The call it makes is this (I have no control over this):
http://localhost/Wizmo-web/Content/data/Listings.json?$callback=jQuery112103831734413679999_1470962161424&"%"24inlinecount=allpages&"%"24format=json
It is returning data from my Listings.json (which I've ensured is valid):
[
{
"Id":557,
"State":"active",
"Title":"Matching Father Son Shirts I Am Your Father Shirt ",
},
{
"Id":558,
"State":"active",
"Title":"Baseball Hoodies Im All About That Base Hooded Swe",
}
]
But my grid is empty.
No errors, no nothing.
Stumped.
I looks like in your controller, you are trying to use the jQuery implementation of Kendo, instead of the supported Angular directives.
The Kendo UI grid features inherent integration with AngularJS using directives which are officially supported as part of the product. To make use of this integration, you need to reference the Angular scripts in your app and register the module incorporating the Kendo UI directives in the following way:
angular.module("myApp", [ "kendo.directives" ])
So in your controller, instead of using jQuery $("#grid").kendoGrid(...) to find the element and add your config object, you are actually going to use a config object on your controller scope:
$scope.mainGridOptions = {
//all your config options here
};
Then in your view, instead of using just <div id="grid"></div> you're actually going to use the Kendo directive here, and pass it the config object from your controller:
<kendo-grid options="mainGridOptions">
...
Kendo has some pretty good documentation on Angular implementation here
The actual problem is different - the dataSource configuration includes a type: "odata" setting, which does not correspond to the server response, so it should be removed. With this setting, the Kendo UI DataSource instance is not able to find the data items in the returned JSON, that's why no table rows are rendered.
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-type
Here is a runnable example without the type setting:
http://dojo.telerik.com/ESija
The moment I add [ 'kendo.directives' ] to the module, everything dies. No errors, nothing.
Controller:
(function() {
'use strict';
angular
.module('WizmoApp', [ 'kendo.directives' ])
.controller('listingsController', listingsController);
listingsController.$inject = ['$http', '$location', '$stateParams', '$filter', 'toastr', 'DTOptionsBuilder', 'DTColumnDefBuilder', 'listingsService', 'datatableService', 'ngAuthSettings'];
function listingsController($http, $location, $stateParams, $filter, toastr, DTOptionsBuilder, DTColumnDefBuilder, listingsService, datatableService, ngAuthSettings) {
...
index.html:
<script src="Content/vendor/Metronic/global/plugins/jquery.min.js" type="text/javascript"></script>
...
<script src="Content/vendor/Metronic/global/plugins/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="Content/vendor/datatables/media/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script src="Content/vendor/angular/angular.min.js" type="text/javascript"></script>
<script src="Content/vendor/KendoUI/js/kendo.all.min.js"></script>
I am trying with EXT JS 4, Sencha Touch 2.0 and WebORB.
What I am trying to build a store in MVC of Sencha Touch through Ext dynamically.
I have called the below javascript function as below in the section in Index.html:
<script src="sencha-touch-all.js"></script>
<script src="webORB.js"></script>
<script>
var dataFetched;
var dataGet=function(){
<!-- Class Name and URL are replaced in the original program-->
this.proxy = webORB.bind("ClassName", "URL");
dataFetched=this.proxy.GetClassList(1301722);
//console.log(dataFetched);
}
</script>
<script src="app.js">
</script>
The following is my app.js
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'SBR',
controllers: [
'Main','Blog','Comments'
],
views : [
'Home','Blog', 'Comments'
],
models : ['Comments'],
stores: ['Comments'],
launch: function(){
dataGet();
console.log(dataFetched);
Ext.create('SBR.view.Viewport');
}
});
The following is my Comment.js - Store
Ext.define('SBR.store.Comments',{
extend: 'Ext.data.Store',
config: {
model: 'SBR.model.Comments',
data: dataFetched
}
});
The following is Comment.js - Model
Ext.define('SBR.model.Comments',{
extend: 'Ext.data.Model',
config: {
//fields: ['subject','body']
fields: ['bookImageUrl','authorFirstName','authorLastName']
}
})
The following is the Comment.js - View
Ext.define('SBR.view.Comments',{
extend: 'Ext.List',
xtype: 'commentspage',
config:{
title: 'Comments',
iconCls: 'star',
//indexBar: true,
store : 'Comments',
itemTpl: '{authorLastName}',
onItemDisclosure: function(item) {
console.log('Disclose more info on' + " " + item.data.subject);
}
}
});
If I define the store with static Json Data it is working fine, but when I try to access it with WebORB it does not.
The console entries are done before it shows data to the console. Why it is not showing any data in the comment's view or my approach is entirely wrong for collecting and loading data through WebORB to the store?
Oh Yes... I got it....
I just changed the following:
I transferred the function dataget() from index.html to Comments.js-Store and called the same function inside the config of the same file like:
data: dataGet()
Thats it...it worked..
I want to inject an old style, procedurally built string into a DIV element that's created in a standard ExtJS 4 MVC application, and I'm having a hard time wrapping my head around how I'm supposed to leverage dynamic loading.
So say I have this function by itself in a javascript file called "createHtml.js":
function fillDiv(strDivName) {
document.getElementById(strDivName).innerHTML = "<h1>TEST</h1>";
}
Elsewhere, in my MVC ExtJS 4 app (so in an object referenced within app.js, I have the following:
myPanel = Ext.create('Ext.panel.Panel', {
title: 'Map',
html: '<div style="width:100%; height:100%" id="map"></div>'
});
In my index.html page, I include a reference to createHtml.js. In my app.js file, I have something like the following:
( function() {
Ext.Loader.setConfig({
enabled : true,
paths : {
MyJive: 'media/js/ext/MyCom/MyJive',
}
});
Ext.onReady( function() {
var urlparams = document.URL.split('?')[1];
var param = Ext.urlDecode( urlparams ? urlparams : '' );
var pcard = Ext.create( 'MyJive.view.MyUI',{
param1 : param.param1,
param2: param.param2
});
Ext.create( 'Ext.container.Viewport', {
layout: 'fit',
items: [pcard]
});
});
})();
Now if I attach a listener to a button somewhere on MyUI and have it call fillDiv('map'); I get a Uncaught ReferenceError: fillDiv is not defined error.
If I put fillDiv not in its own file (createHtml.js) but MyUI.js (referenced by pcard, above), I'm golden. So I know it's not a super-stupid issue like having the div id wrong or some wacky, invalid innerHTML value.
I would have thought the app would know about fillDiv() because fillDiv()'s parent file is in index.html's javascript includes, but fine, createHtml.js isn't being dynamically loaded. I've got that, I guess.
But how do I tell app.js that my function exists in a file outside of its bounds?
(Now, "IRL", I've got fillDiv creating a complicated piece of html via OpenLayers so that we can display a map identified by param1 and param2 embedded in the ExtJS form, but I've gone to this simpler setup to try and figure out what I'm doing wrong.)
EDIT: Added index.html. createHtml.js contains the fillDiv() method. Note that the DIV that takes the map isn't in the index.html; it's, again, defined in an ExtJS Panel.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My Project</title>
<link rel="stylesheet" type="text/css"
href="media/js/ext/ext-4.0/css/ext-all.css" />
<link rel="stylesheet" type="text/css"
href="media/js/ext/MyCom/MyJive/css/main.css" />
<script type="text/javascript"
src="media/js/ext/MyCom/MyJive/createHtml.js"></script>
<script type="text/javascript"
src="media/js/ext/MyCom/MyJive/OpenLayers-2.11/OpenLayers.js"></script>
<script type="text/javascript"
src="media/js/ext/ext-4.0/ext-all-debug-w-comments.js"></script>
<script type="text/javascript"
src="media/js/ext/MyCom/MyJive/app.js"></script>
</head>
<body>
<div id="divParent"></div>
</body>
</html>
EDIT: Adding app.js:
( function() {
Ext.Loader.setConfig({
enabled : true,
paths : {
MyProj: 'media/js/ext/MyCom/MyProj',
OpenLayers: 'media/js/ext/MyCom/MapJive/OpenLayers-2.11',
MyComExt : 'media/js/ext/MyCom/MyComExt'
}
});
Ext.onReady( function() {
var urlparams = document.URL.split('?')[1];
var param = Ext.urlDecode( urlparams ? urlparams : '' );
var pcard = Ext.create( 'MyProj.view.MyProj',{
param1: param.p1,
param2: param.p2
});
Ext.create( 'Ext.container.Viewport', {
layout: 'fit',
items: [pcard]
});
});
})();
I would leave just a comment, but I don't have enough points for that.
You didn't include a index.html file with imports of your createHtml.js and app.js files. But the first thing I would check is that your createHtml.js import is placed above app.js.