PDA

View Full Version : [FIXED] Ext.getStore(id) not working Ext.getStore(name) working...



FBNitro
16 Apr 2015, 6:58 AM
I'm migrating a Sencha Touch 2.4.1 app to ExtJS6. I've noticed that Ext.getStore(storeId) is not working, while Ext.getStore(name) is working.



Ext.define('MyApp.store.ConfigStore', {
extend: Ext.data.Store,
config: {
model: 'MyApp.model.ConfigModel',
storeId: 'configstore'
}
};



var store1 = Ext.getStore('ConfigStore'); // a store is returned
var store2 = Ext.getStore('configstore'); // undefined is returned

ljt

evant
18 Apr 2015, 12:59 PM
This doesn't seem correct. Can you put some logging code inside Ext.data.StoreManager.register and see what gets pushed into that collection? It would also be useful to see some more code, for example: Are you creating the store, or is it being auto created by being included in the stores collection of an application?

FBNitro
20 Apr 2015, 8:42 AM
I have both in the Application. Some are created at runtime, others are in the stores collection of the application. Both have the same issue from what I can see.

The below sample is my app.js stores collection.

Here's the definition of this store (trimmed off the proxy):


Ext.define('MyApp.store.ConfigStore', {
extend: Ext.data.Store,
config: {
model: 'MyApp.model.ConfigModel',
storeId: 'configstore',
autoLoad: true
}
});


This is what I did for the logging:

register: function () {
for (var i = 0,
s; (s = arguments[i]) ; i++) {
console.log(s)
this.add(s);
}
},

Here's the logged output:



[object Object]
{
[functions]: ,
$className: "MyApp.store.ConfigStore",
$configPrefixed: false,
$configStrict: false,
$eventOptions: { },
$links: null,
$observableMixedIn: 1,
$orderToPriority: { },
__proto__: { },
_extraKeys: null,
addRecordsOptions: { },
alias: [ ],
associatedEntity: null,
autoDestroy: undefined,
autoFilter: true,
autoLoad: true,
autoLoadDelay: 1,
autoSort: true,
autoSync: false,
autoSyncSuspended: 0,
batchUpdateMode: "operation",
blockLoadCounter: 1,
byInternalId: { },
clearOnPageLoad: true,
clearRemovedOnLoad: true,
complete: false,
config: { },
currentPage: 1,
data: { },
defaultConfig: { },
defaultIdPrefix: "ext-",
defaultIdSeparator: "-",
destroyed: false,
eventedBeforeEventNames: { },
events: { },
eventsSuspended: 0,
extraKeys: null,
fields: null,
filters: { },
groupDir: "ASC",
grouper: null,
hasListeners: { },
idCleanRegex: [regex] /\.|[^\w\-]/g,
identifiablePrefix: "ext-data-store-",
implicitModel: "Ext.data.Model",
initialConfig: { },
isConfiguring: false,
isFirstInstance: true,
isIdentifiable: true,
isInitializing: false,
isInstance: true,
isObservable: true,
isStore: true,
loadCount: 0,
loading: false,
loadsWhileBlocked: 0,
loadTask: { },
managedListeners: [ ],
mixinConfig: { },
mixins: { },
moveMapCount: 0,
pageSize: 25,
proxy: { },
remoteFilter: false,
remoteSort: false,
removed: [ ],
role: null,
session: null,
sorters: { },
sortOnLoad: true,
statefulFilters: false,
storeId: "ConfigStore",
superclass: { },
trackRemoved: true,
updating: 0,
xtype: undefined,
xtypes: [ ],
xtypesChain: [ ],
xtypesMap: { }
}


As you can see the storeId is mixed case once it gets here...

I believe I have traced the defect back to this function, in Ext.app.Controller.


/**
* Returns instance of a {@link Ext.data.Store Store} with the given name.
* When store doesn't exist yet, it's created.
*
* @param {String} name
*
* @return {Ext.data.Store} a store instance.
*/
getStore: function(name) {
var storeId, store;
storeId = (name.indexOf('@') === -1) ? name : name.split('@')[0];
store = Ext.StoreManager.get(storeId);
if (!store) {
name = Ext.app.Controller.getFullName(name, 'store', this.$namespace);
if (name) {
store = Ext.create(name.absoluteName, {
storeId: storeId
});
}
}
return store;
},

Instead of getting the storeId from the Config section in my Object, it is generating it based on the name of the class. This is part of the stacktrace if I print it out:

constructor [app.js] Line 49199 Script
callParent [app.js] Line 10079 Script
constructor [app.js] Line 58266 Script
callParent [app.js] Line 10079 Script
constructor [app.js] Line 61875 Script
constructor [app.js] Line 10660 Script
[External Code]
create [app.js] Line 12991 Script
getStore [app.js] Line 64579 Script

mitchellsimoens
21 Apr 2015, 2:32 AM
This is a bug that I can trace even back to Ext JS 4.2.0. The getStore method of Ext.app.Controller sets the storeId based on the class name, it doesn't check to see if it has a storeId on it's prototype.


getStore: function(name) {
var storeId, store;

storeId = (name.indexOf('@') === -1) ? name : name.split('@')[0];
store = Ext.StoreManager.get(storeId);

if (!store) {
name = Ext.app.Controller.getFullName(name, 'store', this.$namespace);

if (name) {
store = Ext.create(name.absoluteName, {
storeId: storeId
});
}
}

return store;
}

FBNitro
21 Apr 2015, 6:16 AM
I'm coming from Sencha Touch, where we don't have this issue... so as more projects migrate from Sencha Touch to Ext6 they are going to hit this. Thanks for raising the defect.

mitchellsimoens
21 Apr 2015, 6:22 AM
I'm coming from Sencha Touch, where we don't have this issue... so as more projects migrate from Sencha Touch to Ext6 they are going to hit this. Thanks for raising the defect.

Understood, in Ext JS 6, Sencha Touch was merged into Ext JS for the most part and the code controlling the stores array in Ext.application is using the Ext JS code not the Sencha Touch version which does handle this:


instantiateStores: function() {
var stores = this.getStores(),
length = stores.length,
store, storeClass, storeName, splits, i;

for (i = 0; i < length; i++) {
store = stores[i];

if (Ext.data && Ext.data.Store && !(store instanceof Ext.data.Store)) {
if (Ext.isString(store)) {
storeName = store;
storeClass = Ext.ClassManager.classes[store];

store = {
xclass: store
};

//we don't want to wipe out a configured storeId in the app's Store subclass so need
//to check for this first
if (storeClass.prototype.defaultConfig.storeId === undefined) {
splits = storeName.split('.');
store.id = splits[splits.length - 1];
}
}

stores[i] = Ext.factory(store, Ext.data.Store);
}
}

this.setStores(stores);
}