MVC paths in Extjs - extjs

I have got a ExtJs application (MVC).
So, I define many controllers, models, views and stores.
At now, the structure of my project is not easy.
For example my model:
Ext.define('KP.model.account.AccountList', {
extend: 'Ext.data.Model',
fields: ['parameter', 'string_value']
});
I define my store with model like this:
Ext.define('KP.store.account.AccountList', {
extend: 'Ext.data.Store',
alias: 'store.s_AccountList',
model: 'KP.model.account.AccountList',
......................................
});
If I want to move some .js files, I must rewrite many paths in classes definitions.
So, how can I declare my classes (by alias maybe) and use them more effectively?
It's need, If I move files on files tree.
Thanks!

I believe stores are the only classes that refer to Model classes by their full name. Controllers refer to model classes by their name minus the 'AppName.model' prefix. So a model MyApp.model.User is referred in the controller class as simply User.
If you have a finer grain separation of code than MyApp.model.specific.User is referred by controller as specific.User .
Aliases are used to register xtypes and are also used by the Ext.widget method.

Related

EXTJS how to access global variables in store

I'm quite new to Extjs, I'm needing to pass some data to my stores, I mean, I need to fetch some URL from a singleton configuration file, but reading in the Official documentation I am not able to find a require method in the store. So, I wonder how to tell my store to fetch that URL from a configuration file?
I am not sure which version of Extjs you are using. The answer is based on Extjs6 which I am using. We add the singleton (mostly common configs) files in the application(Application.js) level so that the file will be available across the entire app.
For example,
singleton file is 'Some.Globals.configs'
//Application.js
Ext.define('Some.Application', {
extend: 'Ext.app.Application',
requires: [
'Some.Globals.configs'
]
});
Then anywhere in the application, you can access directly as mentioned below.
Some.Globals.configs.respectiveConfig
If you are extending Ext.data.Store you should be able to use requires property
eg.
Ext.define('My.awesome.Store', {
extend: 'Ext.data.Store',
requires: [
'My.global.Config'
]
...
});

Data-binding in Widgets

I am trying to data-bind a app/Models/mymodel.js in app/widgets/mywidget/widget.xml
<Collection src="mymodel" instance="true" id="aModel" />
I get the following error:
[ERROR] : Script Error Couldn't find module: alloy/widgets/mywidget/models/mymodel for architecture: x86_64
Not specifying WPATH in widget/ctrl.js and widget/style.tss resulting in Alloy.create* methods pick up from app/ controller or models.
Is there a way to specify to use app/Model in widget/xml
Widgets are independent. They're supposed to be shared across apps. So having a dependency on the app, or a specific model, is not the way it is supposed to be and it is designed so it won't work for this reason.
If you've written the widget yourself specifically for this app remove it, and move code to a separate controller.
If you want to share the widget across apps and want to use a collection inside it, make an exported function and provide the collection to it.
In your widget create a model file with a generic name. Include that collection inside your widget.xml. Then in your widget.js create a method to import the collection
exports.setCollection = function(collection){
$.myCollection.reset(collection.models);
}
Then in your controller including the widget:
$.myWidget.setCollection($.myOtherCollection);
This will set all models of the imported collection to the widget collection. Have an ID attribute that doesn't match? Do some converting in the setCollection method so ID does match. That way it is reusable across apps.
For example, your ID attribute is ObjectId, then you this:
exports.setCollection = function(collection, IdAttribute){
_.each(collection, function(model){
model.set({id: model.get(IdAttribute)}, {silent: true});
});
$.myCollection.reset(collection.models);
}
Then in your controller including the widget:
$.myWidget.setCollection($.myOtherCollection,'ObjectId');
Then you've transformed your collection and all should work

ExtJS5 Namespace Confusion

I am completely confused on the namespaces in ExtJS5 application. I am using a common folder under the sencha workspace where I keep code I will be using for multiple pages (multiple SPA's). In one application definition I have the following snippet:
Ext.define('Admin.Application', {
extend: 'Ext.app.Application',
name: 'Admin',
namespaces: ['ALT'],
requires:[
'ALT.GlobalLib',
.....
In my common/src folder I have a file called AltGlobalLib.js with the following snippet:
Ext.define('ALT.GlobalLib',{
extend: 'Ext.app.Controller',
/**/
/** Custom Field Manipulation Methods
/**/
...
The file is loaded but I get a warning the the namespace for ALT.GlobalLib is missing and to add it to my Application Class namespace properties.Possible to get a firm example of how to properly separate the common code from the rest of the apps? Thanks!
I think you need to setPath and designate the name and folder.
Check out the docs on this. And particular setPath on Ext.Loader in the api docs
Here is an example:
Ext.Loader.setPath('NameSpace', '../path/to/files');

M, V, C arrays vs require array inside Controller

What is the Sencha's way of preloading the dependencies?
Inside controller, is it better to put views, stores in arrays like this:
views: ['Full.Path.To.View', 'Full.Path.To.View'],
stores: ['Full.Path.To.Store', 'Full.Path.To.Store']
or just inside requires:
requires: ['Full.Path.To.View', 'Full.Path.To.View', 'Full.Path.To.Store', 'Full.Path.To.Store']
In some cases (when I want Ext.syncRequire()) works only the second option so I wanted your opinion. So, this is being called inside Controller, not inside app.js in Ext.application.
Thank you!
EDIT:
This is my solution and vision of how it should be:
var views = ['MyApp.view.Login.LoginForm', 'MyApp.view.Main.Index'];
var models = ['MyApp.model.Company'];
var stores = ['MyApp.store.Tables'];
var senchaData = ['Ext.field.Text', 'Ext.Button'];
var dependencies = [].concat(views, models, stores, senchaData);
Ext.define('MyApp.controller.Login', {
extend: 'Ext.app.Controller',
requires: dependencies,
config: {
refs: {
loginForm: '#loginForm',
loginButton: '#loginForm #loginButton'
},
control: {
loginButton: {
tap: 'onLogin'
}
}
}...
You have to understand how controller dependencies get resolved by the classmanager because that makes the difference.
Note: Last time I dig into the controller classes was with version ExtJS4.2 so something might have change slightly.
These arrays (models,views,controllers) have some benefits.
One benefit is cleaner code due to the different arrays a second is that the controller can predict the namespace of each class base on the app namespace and the array. You have to know that these arrays get resolved a definition time!
Now these three arrays are nice but the classmanager didn't know them that is why the Ext.app.Controller inject a appropriate hooks for doing so. The hook get triggered when the class get extended and will require all classes found in one of the four array (models,stores,views,controllers). This force the classmanager to load these classes immediately.
Note that the Ext.app.Application is the only one that initializes the controllers, but since ExtJS4.2 it is possible to do it your own with only little effort.
That is all I can say based on your info. If this doesn't help please be more precise in which case loading fails.
Edit
Why not define it this way? It is better to read, isn't it?
Ext.define('MyApp.controller.Login', {
extend: 'Ext.app.Controller',
views: ['Login.LoginForm', 'Main.Index'],
models: ['Company'],
stores: ['Tables'],
requires: ['Ext.field.Text', 'Ext.Button'];
//...
}

Using a single store on multiple grids and dropdowns with extjs 4.1

I have a store "Contacts". In my application i'm using this in 2 grids and 1 combo box. In Each of these components have varying screen space so i need to define pageSize. What is the best practise for this scenario. Is it better do create 3 different stores. ( I'm using MVC ) . If so, are there naming conventions.
Edit
Currently i load the stores in the onLaunch method in my controller
var partsStore = this.getPartsStore();
partsStore.pageSize = 15;
partsStore.load({
scope: this
});
and reference this store in my view
Ext.define('Mis.view.JobPartList', {
extend: 'Ext.grid.Panel',
alias: 'widget.jobpartlist',
store: 'Parts',
Yes, you should create multiple store instances. Not sure what you mean about naming conventions, the store name should stay the same whether you have 1 or multiple instances.
Based on the code you've posted above, it's not going to work, because by adding it to the class definition you're telling it to explicitly share the store.
Ext.define('Foo', {
// ...
initComponent: function(){
this.store = new MyStoreType();
// ...
this.callParent();
}
});

Resources