At the moment our team evaluate possibility of converting large corporate web-application (kind of a ERP system, 600+ unique screens) using ExtJS for the front end. The application was build on our open sourced eludia engine
Our engine requires Model definition (it morphs database as you edit definition), have some kind of Controller (Content modules) and Presentation (Presentation modules with code that generates actual js+html mix)
Like some people from this thread our team has a problem:
We'd like to have Model and View in server side and just to send JSON-data to the front-end
Currently eludia core developers(=my team, we maintain both this application and eludia) have done some steps toward morphing engine to use ExtJS as front end
My team is considering:
Can Ext.app.Application.controllers ... be generated dynamically?
Therefore these questions, ordered by fuzziness:
UPDATE
I should try to narrow question
One doesn't need to load all controllers at once during app startup?
What I trying to say, maybe it is possible to load controllers in a more 'dynamic' approach:
The best way for you to use controller on-demand is to load them dynamically and create instances of controllers when needed. Also you need to put your controllers in separate js files, so the schema will be the following:
//let's say you need to use controller User:
var controller = ControllerManager.get('User');//I believe you have some controller manager, similar to Sencha's Ext.ControllerManager
if(controller){
//use it here
}
else {
loadScript([url of your controller script], controllerLoaded);
}
...
function controllerLoaded(){
//create controller instance here if needed and use it then
}
...
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
UPDATE
In order to integrate new controller into already running Ext.app.Application
you need to extend Ext.app.Application
and add the following method:
addController: function(name){
//at this point your controller .js file should be already loaded into the DOM
var c = this.getController(name); //controller will be created automatically by name in this getter
//perform the same initialization steps as it would have during normal ExtJs process
c.init(this);
с.onLaunch(this);
}
Btw, instead of using custom method to load javascript file dynamically you can use ExtJs builtin method of Ext.Loader
:
/**
* Load a script file, supports both asynchronous and synchronous approaches
*
* @param {String} url
* @param {Function} onLoad
* @param {Object} scope
* @param {Boolean} synchronous
* @private
*/
loadScriptFile: function(url, onLoad, onError, scope, synchronous)
Your best bet is to depend on Ext.Loader
, but do not use loadScriptFile()
method as suggested above.
Ext 4 introduces a class system. One of (many) benefits of that is dep-tree that allows you to manage all your inter-component dependencies and load classes as needed.
Here is how you initialize loader
Ext.Loader.setPath('App','/js/app');
Ext.Loader.setPath('WidgetsLibrary','/js/widgets');
Ext.Loader.setConfig({enabled: true});
Define a dynamically-loaded controller class:
Ext.define('App.controller.Menu', {
extend: 'Ext.app.Controller', // leave it as it is
models: ['Event','User'], // this assumes App.model.* prefix
stores: ['Options','Permissions'], // this assumes App.store.* prefix
views: ['menu.Bar','SmartButton'],// this assumes App.view.* prefix
requires: [
'App.whatever.other.class', // auto-load this class as a dependency
'WidgetsLibrary.*', // auto-load all classes in WidgetsLibrary
],
init: function(){}
// [...]
Now to dynamically-load your controller class (a mockup):
Ext.require(
'App.controller.Menu', // this auto-loads all dependencies
function(){
// ... as soon as this class
// and all its dependencies have loaded...
var controller = Ext.create('App.controller.Menu'); // create an instance
controller.init(); // launch init() method
}
);
BONUS: by using class system and loader, you don't have to maintain your own controller collection and check if controller has been loaded or not. Just use Ext.ClassManager.isCreated()
method described here.
if(Ext.ClassManager.isCreated('App.controller.Menu')){
// ... controller has already been loaded and init ...
}else{
// we need to auto-load that controller using Ext.require()
}
More reading:
We just went through this with our webapp. ~250 screens. Yes, we load our controllers dynamically.
Time to build a screen using Ext.JS is about 400% faster than using YUI, which was our previous platform. Nice bit was that we could keep the YUI Connect object which works with better efficiency than the Ext.JS version.
We have an App class that manages the loading and initializing of Ext.JS controllers. Here, we use the only other YUI class in our code which is YUI.get (YUI.get.script). Just make sure you don't load a controller twice in the same session.
I assume you want to dynamically load these controllers for loading time (which is what we struggled with initially too). EXTEND, EXTEND, EXTEND.
Ext.define('namespace.classname', {
{
extend: 'Ext.form.panel',
// your code here
}
This will lower your overall code downloading, and speed up the initialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With