ExtJS MVC: should controllers be specified within requires for application? - javascript

If an Ext.application has the following controllers:
Ext.Loader.setConfig({enabled:true});
Ext.application({
name: 'MyApp',
appFolder: 'app',
controllers: [
'Ctrl1',
'Ctrl2'
],
launch: function() { ... }
});
should it also include the controllers in controllers in the requires section, i.e. add
requires: [
'MyApp.controller.Ctrl1',
'MyApp.controller.Ctrl2'
],
within the above class?

The short answer is NO.
The long answer is that the controllers, models, views and stores configs all translate to requires. The bit that does the magic is in the Ext.app.Controller class:
onClassExtended: function(cls, data, hooks) {
var Controller = Ext.app.Controller,
className, namespace, onBeforeClassCreated, requires, proto, match;
className = Ext.getClassName(cls);
namespace = Ext.Loader.getPrefix(className) ||
((match = className.match(/^(.*)\.controller\./)) && match[1]);
if (namespace && namespace !== className) {
onBeforeClassCreated = hooks.onBeforeCreated;
requires = [];
hooks.onBeforeCreated = function(cls, data) {
proto = cls.prototype;
Controller.processDependencies(proto, requires, namespace, 'model', data.models);
Controller.processDependencies(proto, requires, namespace, 'view', data.views);
Controller.processDependencies(proto, requires, namespace, 'store', data.stores);
Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers);
// this is the line to look at!!!
Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));
};
}
},
Your application is just an Ext.app.Application class that inherits from Ext.app.Controller; thus the controllers config also translates to requires.

No, that is not necessary. Here is an example of working app.js I am using right now:
Ext.Loader.setConfig({enabled:true});
Ext.Loader.setPath('Ext.ux', '../extjs/examples/ux');
Ext.application({
name: 'FPPP',
autoCreateViewport: true,
controllers: [
'Main',
'List',
'Report'
]
});
There's also the Sencha MVC guide

Related

Creation of a global, persistent object into Extjs

Good day all.
I'm into a big project that uses EXTjs (i guess it's 4.0), the project is huge and have several years behind.
I'm not into Extjs so I'm trying to learn what to do and how to do it, and my new task is to create a persistent, global object, available into the whole application in which I need to store some information that are used in different parts of the project (let's say for example that the user can set a particular property of this object to "true" while doing some actions and this "true" it will be used into another viewcontroller to enable some functions, things like this).
so, I've created a new file called userJsonMainModel.js :
Ext.define('Tac3.userJsonMainModel', {
extend: 'Ext.data.Model',
constructor: function() {
var userJsonMainModel = this;
userJsonMainModel.callParent(arguments);
userJsonMainModel.data.tmp = {};
},
testProperty:{foo:"bar"},
testMethod: function (){
console.log("testFunction called");
}
});
and in Application.js :
requires: [
...
'Tac.userJsonMainModel'
],
stores: ['Countries', 'Kpis', 'Dimensions'],
autoCreateViewport: false,
init: function() {
var controller = this
Ext.tip.QuickTipManager.init();
Ext.setGlyphFontFamily('FontAwesome');
var userJsonMainModel = controller.createUserJsonMainModel();
console.log("into init: ", this.userJsonMainModel.testProperty);
...
createUserJsonMainModel: function() {
var controller = this;
controller.userJsonMainModel = Ext.create('Tac3.userJsonMainModel', {
controller: controller
});
console.log("check if the jsonmainmodel exist ",controller.userJsonMainModel.testProperty);
},
this is actually working, now the second step is to access the same object from another view (or its viewcontroller), this is what I've done into a a viewController:
Ext.define('Tac3.view.udesign.UdesignController', {
extend: 'Ext.app.ViewController',
alias: 'controller.udesign',
init: function(view) {
...
console.log("into init: ", this.userJsonMainModel.testProperty);
}
and this is actually throwing a:
Uncaught TypeError: Cannot read property 'testProperty' of undefined
I was pretty sure the objects defined into application.js would be globally accessible, but I guess I'm wrong, or doing something in a wrong way.
since I've found quite no examples on this topic (which is probably because it is not a standard way to do this), I'd like to ask what I'm doing wrong?
Just define a class and require it in your application:
Ext.define('MyApp.Globals', {
singleton: true,
foo: 100,
bar: 'baz'
});

Ext.getStore() returns undefined while testing with Siesta

In ExtJs application to make getStore work controllers, models and stores are added in Application.js. But for testing with siesta, I can't make any changes in Application.js.
Calling Ext.getStore(storeId) directly is returning undefined. I have tried by adding model in preload, but it doesn't help.
What should I do for this?
-------------------------Code in the testFile AnalysisController.t.js ---------------------
StartTest(function(t){
var testStore = Ext.getStore('Nm.store.analysis.TestStore'); //testStore is undefined
});
-------------------------Code in testModel.js-------------------------
Ext.define('Nm.model.analysis.TestModel',
{
extend: 'Ext.data.Model',
fields: [
{name:'lastName',type:'string'},
{name:'age',type:'int'},
{name:'relationDescription',type:'string'},
{name:'dateOfBirth',type:'date',dateFormat: 'm-D-Y'}
]
});
-------------------------Code in testStore.js-------------------------
Ext.define('Nm.store.analysis.TestStore',{
extend : 'Ext.data.Store',
requires: ['Nm.model.analysis.TestModel'],
model : 'Nm.model.analysis.TestModel'
});
-------------------------Code in harness file testIndex.js----------------
var Harness = Siesta.Harness.Browser.ExtJS;
Harness.configure({
title : 'Samples',
loaderPath : { 'Nm' : 'app' },
preload : [
"http://cdn.sencha.io/ext/gpl/4.2.0/resources/css/ext-all.css",
"http://cdn.sencha.io/ext/gpl/4.2.0/ext-all-debug.js"
]
});
Harness.start({
group : 'Controller',
items : [
'test/AnalysisController.t.js'
]}
);
to use Ext.getStore() you have to register the store I think.
plz read
Check if Ext is defined in your test file. Although Siesta supports Ext, the variable Ext is not defined by default. The simplest way to do this is just by adding the following at the top of your test:
var Ext = test.global.Ext;
To load a "global" store via Ext.getStore(), it must be registered in the application.
To do that, ensure it is added to the stores array in your main app class
Ext.application({
extend: 'Ext.app.Application',
stores: [ add global store classes here ]
});

ExtJS 4.2.1 - issue with refs and controllers

I have my label defined as follows:
Ext.define('CapHour.view.CapHourLabel', {
extend: 'Ext.form.Label',
alias: 'widget.caphourlabel',
//itemId: 'capHourLabel',
itemId: 'label',
style: 'display:inline-block;text-align:center'
})
And my controller defined like this:
Ext.define('CapHour.controller.CapHourController', {
extend: 'Ext.app.Controller',
stores: ['CapHour'],
refs: [
{
ref: 'label',
selector: 'label'
}
],
init: function() {
var store = this.getCapHourStore();
store.on('load', function(records, operation, success) {
var label = Ext.ComponentQuery.query('#label')[0],
//var label = this.getCapHourLabel(),
hour = records.getAt(0).get('hour');
label.setText('CAP HOUR<br/>'+hour, false);
})
}
})
I can use Ext.ComponentQuery.query() just fine, but when I try to use this.getLabel(), the API call returns undefined. Is there something I'm forgetting? I tried setting the selector in the ref to 'label' and '#label' but I keep getting the same result.
You need to set the scope of the store callback to be the controller:
store.load({
scope: this,
callback: function(records) {
console.log(this.getLabel());
}
});
As a side note, you'll probably want a better selector. The current selector you have searches by xtype, globally, so that means 'grab the first thing you see that has an xtype label'.

Accessing variables across different scopes in Javascript & YUI 3

I'm new to YUI 3 and YUI in general. I'm trying to pass data between classes and methods.
In this example I'm using the gallery-sm-treeview plugin to build a file tree. There's a class named TreeView to initialize and render the tree. There's another class named MenuBar where I want to access some of the plugin-specific methods through TreeView's getter method.
However, the variable var treeview inside the YUI().use() scope is of course not accessible from outside. How to do it?
YUI.add('treetool.TreeView', function(Y) {
Y.treetool.TreeView = Class.extend({
init : function(elementId) {
YUI({
gallery: 'gallery-2013.06.20-02-07'}).use('gallery-sm-treeview', function (Y) {
// Create a new TreeView with a few nodes.
var treeview = new Y.TreeView({
// Tell the TreeView where to render itself.
container: elementId,
// Populate the treeview with some tree nodes.
nodes: [
{label: 'Node 1'},
{label: 'Node 2', children: [
{label: 'Child 1'},
]
});
// Render the treeview inside the #treeview element.
treeview.render();
});
},
getSomeData : function () {
return treeview.getSelectedNodes();
}
});
}, '0.0.1', {
requires : [ 'jquery' ]
});
and
YUI.add('treetool.MenuBar', function(Y) {
Y.treetool.MenuBar = Class.extend({
init : function(treeObj) {
var someData = treeObj.getSomeData();
},
});
}, '0.0.1', {
requires : [ 'jquery' ]
});
It might not be the "best" way to do it, but one way would be to define the treeview variable in a scope that is available in both places.
YUI.add('treetool.TreeView', function(Y) {
var treeview;
//...
and
treeview = new Y.TreeView({ // removed "var "

Backbone.js Model does not inherit from collection

I have a model called score and a collection called scores. However, the model does not seem to be inheriting the localStorage property (or for that matter, any property) from the parent collection. Am I missing something here?
Running Backbone with RequireJS.
models/score.js
define([
'underscore',
'backbone',
'localstorage'
], function(_, Backbone, Store){
var ScoreModel = Backbone.Model.extend({
defaults: {
board_id: null,
ns_pair: null,
ew_pair: null,
ns_score: null
},
validate: function(attrs, options){
if( isNaN(attrs.board_id) || attrs.board_id < 1 ){
return 'Invalid Board ID!';
}
},
localStorage: new Store("ScoreCollection")
});
return ScoreModel;
});
collections/scores.js
define([
'underscore',
'backbone',
'models/score',
'localstorage'
], function(_, Backbone, ScoreModel, Store){
var ScoreCollection = Backbone.Collection.extend({
model: ScoreModel,
localStorage: new Store("ScoreCollection")
});
return ScoreCollection;
});
main.js
require.config({
paths: {
// Major libraries
jquery: 'libs/jquery/jquery.min',
underscore: 'libs/underscore/underscore.min',
backbone: 'libs/backbone/backbone.min',
// Require.js plugins
text: 'libs/require/text',
// Backbone.js plugins
localstorage: 'libs/backbone/localstorage',
// Just a short cut so we can put our html outside the js dir
// When you have HTML/CSS designers this aids in keeping them out of the js directory
templates: '../templates'
}
});
// Let's kick off the application
require([
'app'
], function(App){
App.initialize();
});
Backbone Models don't inherit from Backbone Collections. They're just extensions of the base Backbone.Model that you 'extend' with your own properties and methods. Collections, the same deal. You can specify that a collection's model is based on a particular model you've defined so that when collections are added to it, it uses the model constructor to create instances for each model in that collection, but there is no direct inheritance relationship there. You can define a property on a model that happens to be an instance of a collection if that suits your needs.

Categories

Resources