extjsextjs4extjs-mvc

Extjs 4 - Namespaces in plugin like app


I have modular application that contains several modules/plugins, that can also run as standalone applications.

I dynamically register module/plugin controllers to main application and here is the problem in steps.

Code of plugin controller:

 Ext.define('B.controller.PortalController', {
     extend: 'Ext.app.Controller',
     views: [
         'portal.MapPanel',
         'administration.ConfigPanel',
         'administration.ConfigPanelWrapper'
     ],
     //stores:['Test'],
     init: function() {
         console.log('portal controller init');
         //console.log(this.getTestStore());
         this.control({

         });
     }
 });

The views register properly with B prefix, Ext.Loader loads B.view.portal.MapPanel but the store is not loaded.

If I specify stores:['Test'] it tries to load A.store.Test, If I specify test.Test it does nothing (like error but ext-all-debug does not catch it) and if I specify stores:['B.store.Test'] it loads it properly but now I have to use getBStoreTestStore() to get the store reference that will cause a lot of code changing.

How to make the controller to load stores with proper prefix?


Solution

  • Without override I think it is impossible. What is more for my views it should not work also!

    All code from ext-all-debug.js

    Controller loads classess properly using proper prefix using its own classname:

    namespace = Ext.Loader.getPrefix(className) || match[1];
    namespaceAndModule = namespace + '.' + module + '.'
    

    But For each view, store, model its controller creates getter passing name into getStore, getView, getModel function

    if (!this[fn]) {
        this[fn] = Ext.Function.pass(this['get' + type], [ref], this);
    }
    

    The getStore function that getter is passed into returns application store:

    getStore: function(name) {
        return this.application.getStore(name);
    },
    

    Application itself uses getModuleClassName to resolve class name

    getModuleClassName: function(name, module) {
    
        if (name.indexOf('.') !== -1 && (Ext.ClassManager.isCreated(name) || Ext.Loader.isAClassNameWithAKnownPrefix(name))) {
            return name;
        } else {
            return this.name + '.' + module + '.' + name;
        }
    }
    

    So if there is fully qualified class name with known prefix it will return name only otherwise class name will be built using this.name which is application name so using stores:['Test'] will point to A.store.Test.

    I am thinking about writing an override but I am afraid that it will break other things.