Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExtJs 6 stores config on Ext.app.Controller not working

I just noticed that stores config http://docs.sencha.com/extjs/6.0/6.0.2-classic/#!/api/Ext.app.Controller-cfg-stores on Ext.app.Controller is not looking in the right path (happens the same with views config).

e.g

Ext.define('MyApp.controller.Menu', {
    extend: 'Ext.app.Controller',
    stores: ['Menu']
...
});

this will look for

http://localhost/myapp/app/controller/store/Menu.js?_dc=20160607211025

notice the controller folder

instead of

http://localhost/myapp/app/store/Menu.js?_dc=20160607211025

At the beginning I thought this was a configuration issue specific to one of my projects but then got the same thing on a different project.

I am using ExtJs 6.02

I know I can use the full class name like MyApp.store.Menu but then the getter would be very ugly. (This is happening on a huge code base that I just upgraded so using the full class name would be my last resource).

Has someone faced this issue ?

like image 368
code4jhon Avatar asked Oct 30 '22 02:10

code4jhon


1 Answers

I've found the reason (bear with me):

https://docs.sencha.com/extjs/6.0/6.0.2-classic/source/Controller2.html#Ext-app-Controller

look at:

onClassExtended -> Controller.resolveNamespace -> Ext.app.getNamespace

Those are the important ones, once the namespace is resolved there is a call to process dependencies:

Controller.processDependencies(proto, requires, namespace, 'store', data.stores);

I researched this and Ext.app.getNamespace is identical in ext 5 and 6

so why is it in ExtJs 5

Ext.getNamespace("MyApp.controller.SomeController"); // returns MyApp

and on ExtJs 6

Ext.getNamespace("MyApp.controller.SomeController"); // returns MyApp.controller

The reason is found by console.log Ext.ClassManager.paths there is now a new entry that corresponds to MyApp.controller

enter image description here

previously there was no key for MyApp.controller (ZHT.controller)

And what Ext.getNameSpace does is look for the 'deepest prefix' as you can see here http://docs.sencha.com/extjs/6.0/6.0.2-classic/source/Util.html#Ext-app-Util

[update] So one thing that can be done is to override the static method resolveNamespace like this:

  statics: {
    resolveNamespace: function(cls, data) {
            var Controller = Ext.app.Controller,
                namespaceRe = cls.prototype.isProfile ? Controller.profileRegex : Controller.controllerRegex,
                className, namespace, match;
            /*
             * Namespace resolution is tricky business: we should know what namespace
             * this Controller descendant belongs to, or model/store/view dependency
             * resolution will be either ambiguous or plainly not possible. To avoid
             * guessing games we try to look for a forward hint ($namespace) that
             * Application class sets when its onClassExtended gets processed; if that
             * fails we try to deduce namespace from class name.
             *
             * Note that for Ext.app.Application, Controller.onClassExtended gets executed
             * *before* Application.onClassExtended so we have to delay namespace handling
             * until after Application.onClassExtended kicks in, hence it is done in this hook.
             */
            className = Ext.getClassName(cls);
            namespace = data.$namespace || data.namespace ||
                Ext.app.getNamespace(className) ||
                ((match = namespaceRe.exec(className)) && match[1]);

            //<debug>
            if (!namespace) {
                Ext.log.warn("Missing namespace for " + className + ", please define it "+
                    "in namespaces property of your Application class.");
            }
            //</debug>


            //This is the only change on this override.
            //http://stackoverflow.com/questions/37731213/extjs-6-stores-config-on-ext-app-controller-not-working/37733261#37733261
            if(namespace && namespace.indexOf(".controller") > -1) {
                namespace = namespace.slice(0, namespace.indexOf(".controller"));
            }

            return namespace;
        }
  }

If you know of a better solution please let me know!

like image 51
code4jhon Avatar answered Nov 12 '22 12:11

code4jhon