PDA

View Full Version : ArrayStore/ArrayReader broken in 0.94



cdonnellytx
12 Sep 2010, 2:38 PM
Hi all,

It appears that neither the ArrayStore nor the ArrayReader are working properly after updating to 0.94. In fact, the example in the ArrayStore (http://dev.sencha.com/deploy/touch/docs/?class=Ext.data.ArrayStore) docs does not work:


var store = new Ext.data.ArrayStore({
// store configs
autoDestroy: true,
storeId: 'myStore',
// reader configs
idIndex: 0,
fields: [
'company',
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
]
});

var myData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
];

store.loadData(myData);

var rec = store.getAt(0);
console.debug('company: ', rec.get('company')); // this should work, but doesn't
console.debug('0:', rec.get('0')); // this does, but shouldn't
console.debug(rec.data);



prints the following:



company:
0: 3m Co
{
"0": "3m Co",
"1": 71.72,
"2": 0.02,
"3": 0.03,
"4": "9/1 12:00am",
"company": "",
"price": 0,
"change": 0,
"pctChange": 0,
"lastChange": null
}


Shouldn't the rec.data look like



{
"company": "3m Co",
"price": 71.72,
"change": 0.02,
"pctChange": 0.03,
"lastChange": "9/1 12:00am"
}


instead?

evant
12 Sep 2010, 4:29 PM
When calling loadData, the format is always the same regardless of the reader:



loadData([{
field1: 'a',
field2: 'b'
},{
field1: 'c',
field2: 'd'
}]);


I'll add some extra notes to loadData to reflect this.

cdonnellytx
13 Sep 2010, 6:14 AM
I'll add some extra notes to loadData to reflect this.

This also appears to be the case for the data property as well.

So I have a couple of questions:

* At this point, what is the difference between Ext.data.Store and Ext.data.ArrayStore (and JsonStore, etc.)? Is the latter deprecated? Or is it simply a Store that defaults to loading an ArrayReader?
* This differs from how ExtJS interprets the same code; in ExtJS (as of 3.2.2), it maps the data into the record's preferred structure. Is this going to change in a future version of ExtJS as well?

evant
13 Sep 2010, 6:17 AM
1) It's not really overly useful.
2) Touch and Ext 4 will share the same data package, so yes, this behaviour is likely to change.

edspencer
13 Sep 2010, 1:11 PM
There are really two main ways of loading data into a Store - via its configured Proxy or doing it manually. When going via any kind of Proxy that interacts with a server (any ServerProxy subclass), the configured Reader is used to decode the server's response, using any mappings on the model fields in case the server's field names are for some reason.

When loading data manually we assume you already have it in the correct format. This may be an incorrect assumption and I welcome feedback but it strikes me as reasonable that your local data is already a known format.

We're currently working on getting Store up to 1.x quality so a few of these things are still in flux.

cdonnellytx
13 Sep 2010, 3:59 PM
My main issue is that we (at my company) are developing a mobile version of our existing webapp, and so we are leveraging both existing server-side and client-side code (the latter in the form of a base class, which is subclassed in both the desktop webapp (which uses ExtJS 3.x) and the mobile webapp (using Sencha Touch). Many of the smaller data lists (mainly used to drive combo/select lists) are sent down as auxiliary properties in a larger JSON object as arrays (to reduce the number of round trips as well as bandwidth used), and are hydrated into records via ArrayStores in the main webapp.

I have devised a workaround for now where

Store creation is now done in the webapp-specific subclasses, not the base class.
In the Sencha Touch webapp, I am doing something like



createMyStore: function (data) {
var model = 'MyModel';

// Ensure the model is loaded.
if (!Ext.ModelMgr.getModel(model)) {
Ext.regModel(model, {
fields: ['id','foo','bar','baz']
});
}

// Create the store and read the data.
var store = new Ext.data.Store({
autoDestroy: true,
model: model,
proxy: {
type: 'memory',
reader: {
type: 'array',
model: model
}
}
});

if (data) {
store.loadRecords(store.proxy.reader.read(data).records);
}
return store;


I specify the model twice in cases where the Store can either read records from a locally constructed block as well as do read()s against a JSON web service. While that does work, it is somewhat of a large block of code to replicate. If there were a way to make it cleaner/less cumbersome (particularly the loadRecords statement) that would work.

Thanks,
# Chris

jep
18 Jul 2011, 1:40 PM
Argh, yet another Sencha Touch pitfall that I stepped into, burning an hour of my time figuring out why mode code isn't working, breaking it out into an isolated project, trying it there, then trying to Sencha code in docs, scratching my head, etc.

I agree with Chris that it's vital to be able to load data into a store both locally and from a remote source. Not everything fits the exact same set of rails you have nailed onto Store. You're hobbling its functionality by not allowing it to load data locally. In my case, I have an existing code base that uses data that another piece of code is loading from the server. It spits it back as an array. I then wanted to load it into Store. But it appears now that the only way for me to do that and have it work is to rewrite ALL my code in one gulp. That's an incredibly hard thing to do. Or I have to write a bunch of shim code, which is needlessly time consuming and hard to maintain.

If nothing else, there needs to be HUGE glaring warnings around loadData in the docs to educate on how it completely short-circuits the useful behavior you think you are getting.

edspencer
18 Jul 2011, 3:59 PM
Are you referring to the same point above (the idea that loadData should use the Proxy's Reader to decode the data)?

jep
18 Jul 2011, 4:00 PM
Yup. Either via loadData or through another function (with loadData marked in the docs with some big warning signs). I have yet to actually get to a point where I can use a Proxy with any of our existing code base. There's always a little something that is incompatible.

edspencer
18 Jul 2011, 4:05 PM
Ok, I see the benefits of doing this (although it does somewhat abuse Demeter). I've added a feature to develop this

jep
18 Jul 2011, 4:05 PM
Thanks!