6
votes

We're using Ext JS MVC as the front-end technology of a plugin/host architecture, where one host exists and many plugins can be installed easily via xcopy. Each plugin has an Ext JS application, and each plugin registers itself on the load of the page. The overall application is a Single Page Application (SPA).

The major problem that we've encountered now, is that we have more than 10 plugins installed, and each plugin has at least 10 controllers, and more than 50 views, stores, and models. Thus when we refresh our page (F5), we should sit and wait for almost 30 seconds so that something near 200 HTTP requests get to the server, and something near 3 Megabytes of response get back.

Though caching has been applied, but this is not desirable at all. Not even for the first time. I guess even a layman would accept this argument that to get some milk, you shouldn't wait till farm, cows, barns, houses, roads, electricity, river, etc. are built.

The definite answer to this problem must be lazy-loading of controllers, views, stores, and models. However, we don't have a clear picture of what we have to do to get that, and we can't find a good, applicable answer on the web. Most of the discussions are only about the requirement of lazy-loading, but they haven't mentioned how. Look at this link for example:

http://www.sencha.com/forum/showthread.php?130449-Large-Single-Page-Architecture-in-ExtJS-4.0

or this one:

http://www.sencha.com/forum/archive/index.php/t-156694.html?s=aaeec1ce30acbc9cbd2615afadec982f

If we use Ext.require method, then we only load our controllers as simple JavaScript files, and they won't go into their hierarchy to load their stores, views, and models. We have tested that.

On the other hand, we can't find getController() and ControllerManager on Ext JS. Seems that they're gone on Ext JS 4.1.3.

Any idea on how can we load controllers dynamically based on URL parameters (we might need a route engine to parse URL and load controllers dynamically). Even a well-documented article or forum discussion with code samples can help us.

3
That's why I hate Ext JS. Had I asked a jQuery question, I would have gotten more than 5 answers by now.Saeed Neamati
Have you seen this blog post about lazy loading? sencha.com/blog/using-ext-loader-for-your-applicationRichard Marr
@SaeedNeamati ha ha ha... that is not too bad :) each platform has its own strengths and weaknesses.Mahmoud Moravej

3 Answers

3
votes

For your problem you should load controller files on an event like menu click or etc. with the Ext.require. after you this you should initialize your controller.

I read the ExtJs source and implement a custom lazy load controllers on the below.

// this should run first time your application start
Ext.application({
    name: 'AppName',
    appProperty: 'appProp'
});

// below lines should run when you want to load controllers
// (for ex on menuitemclick)
var controllers = ['yourController', 'anotherController'];

Ext.require(controllers, function () {
    for (i = 0; i < controllers.length; i++) {
        var controllerName = controllers[i].substr(controllers[i].lastIndexOf(".") + 1);
        if (!AppName.appProp.controllers.get(controllerName)) {
            var controller = Ext.create(controllers[i], {
                application: AppName.appProp,
                id: controllerName
            });
            controller.init(AppName.appProp);
        }
    }
});
1
votes

Have you tried Ext.create()?

http://docs.sencha.com/extjs/4.2.0/#!/api/Ext-method-create

This method will dynamically load your .js files and it seems to work well. However, it seems that there should be a cleaner way to do this.

0
votes

At least in 4.2.0, this is available. From the Architecting Your App tutorial...

In larger applications, you might want to load additional controllers at runtime. You can do this by using the getController method. When you load additional controllers at runtime, you have to remember to call the init method on the loaded controller manually.

someAction: function() {
  var controller = this.getController('AnotherController');

  // Remember to call the init method manually
  controller.init();
}

Here is a link to the documentation for this feature of Ext.app.Application.