mardi 27 janvier 2015

Data package always considers hash fields to be modified

Please don't give me a hard time for reporting this bug. I've run into it, it's a real problem for data-intensive apps, and I'm trying to help you improve things.

Steps to reproduce:


(1) Create a model (and corresponding store) with a field you expect to be a hash:



Code:



Ext.define('MyApp.model.MyModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'id' },
{ name: 'myobject' }
]
}
});

(2) Load the store once:


Code:



myStore.load();
// [GET "/records.json"] -> { records: [{ id: 1, myobject: { foo: 'bar' } }] }

(3) Load the store again:


Code:



myStore.load();
// [GET "/records.json"] -> { records: [{ id: 1, myobject: { foo: 'bar' } }] }

What's expected:

Sencha Touch goes through its usual routine of instantiating each record, checking the in-memory cache for an existing record, and merging the new data into the existing record. It sees that nothing was changed in the 2nd load, so no bound views are refreshed.


What happens instead:


On the 2nd load, Touch thinks that the hash had changed (JS considers hashes unequal unless pointing to the same reference in memory), even though it's the same hash, and calls Ext.data.Model#endEdit on the record. While it's a small problem with a smaller #'s of records, it's a huge problem with large #'s. For example, if you have 10,000 records in a store, and an infinite list is bound to it, the list will be re-rendered 10,000x (for every endEdit). Ouch.


Solution:


Ext.data.Model#mergeData needs to do a proper check of equality between 2 hashes. Or, if that's prohibitively expensive, at least batch these edits so lists (and any bound views) only unnecessarily update once. Or, ...






Data package always considers hash fields to be modified

Aucun commentaire:

Enregistrer un commentaire