-
13 Jan 2012 6:39 AM #1
[4.1b1] Model#set([Object]) calls endEdit() with empty modifiedFieldNames arg
[4.1b1] Model#set([Object]) calls endEdit() with empty modifiedFieldNames arg
In 4.1.0-beta-1, Model#set([key-value-object]) always calls endEdit() with an empty modifiedFieldNames argument, which causes containing Stores to be notified about data updates with no corresponding modified field names.
Test case:
Code:Ext.create('Ext.data.Store', { fields: ['text'], data: [ {text: 'My name is Earl.'} ], listeners: { update: function(store, record, op, modifiedFieldNames) { // modifiedFieldNames array should not be empty, but it is. console.log('modified field names: ' + Ext.encode(modifiedFieldNames)); }, } }).getAt(0).set({ text: 'My name is not Earl.' });
Fix:
Code:Ext.define('Ext.data.ModelOverride', { override: 'Ext.data.Model', // bugfix -- broken set([Object]) method set: function(fieldName, value) { var me = this, fields = me.fields, modified = me.modified, // modifiedFieldNames = [], field, key, i, currentValue, notEditing, count, length; if (arguments.length == 1 && Ext.isObject(fieldName)) { notEditing = !me.editing; count = 0; fields = me.fields.items; length = fields.length; for (i = 0; i < length; i++) { field = fields[i].name; if (fieldName.hasOwnProperty(field)) { if (!count && notEditing) { me.beginEdit(); } ++count; me.set(field, fieldName[field]); } } if (notEditing && count) { me.endEdit(false /*, modifiedFieldNames */); } } else { fields = me.fields; if (fields) { field = fields.get(fieldName); if (field && field.convert) { value = field.convert(value, me); } } currentValue = me.get(fieldName); me[me.persistenceProperty][fieldName] = value; if (field && field.persist && !me.isEqual(currentValue, value)) { if (me.isModified(fieldName)) { if (me.isEqual(modified[fieldName], value)) { delete modified[fieldName]; me.dirty = false; for (key in modified) { if (modified.hasOwnProperty(key)){ me.dirty = true; break; } } } } else { me.dirty = true; modified[fieldName] = currentValue; } } if(fieldName === me.idProperty && currentValue !== value) { me.fireEvent('idchanged', me, currentValue, value); } if (!me.editing) { me.afterEdit([fieldName]); } } } });
Sencha Docs / Ext 3.x - ( Docs | Examples )
Learning Center / Saki's Examples (for 2.x) / HOWTO - ( Report Bugs | Post Proper Code )
-
16 Jan 2012 9:31 AM #2
* bump *
This appears to affect Touch as well -- I traced it to the shared platform package, and this bug seems to have been there for some time now.
Sencha Docs / Ext 3.x - ( Docs | Examples )
Learning Center / Saki's Examples (for 2.x) / HOWTO - ( Report Bugs | Post Proper Code )
-
8 Feb 2012 10:03 AM #3
Just encountered this myself, in 4.1b2. Would sure be nice to have this fixed in Ext.

-
8 Feb 2012 10:12 AM #4
One other note about the impact of this bug: not only does this affect the "update" events being called with no modified field names, this will also prevent stores configured with autoSync:true from syncing after calls to set() with an object of values to set on the model.
This is because the model's afterEdit() method (called from endEdit()) also passes the modifiedFieldNames argument to the afterEdit() method on the Store. That in turn prevents the store from syncing when it should, since it checks the array of modifiedFieldNames to see if any of the fields specified there need to be persisted.
-
13 Mar 2012 9:00 AM #5
Assuming modifiedFieldNames is still needed, here is a fix:
Code:Ext.require('Ext.data.Model', function() { Ext.define('Override.data.Model', { override : 'Ext.data.Model', set: function(fieldName, value) { var me = this, fields = me.fields, modified = me.modified, modifiedFieldNames = [], field, key, i, currentValue, notEditing, count, length; /* * If we're passed an object, iterate over that object. */ if (arguments.length == 1 && Ext.isObject(fieldName)) { notEditing = !me.editing; count = 0; fields = me.fields.items; length = fields.length; for (i = 0; i < length; i++) { field = fields[i].name; if (fieldName.hasOwnProperty(field)) { currentValue = me.get(field); newValue = fieldName[field]; if (currentValue !== newValue) { modifiedFieldNames.push(field); if (!count && notEditing) { me.beginEdit(); } ++count; me.set(field, fieldName[field]); } } } if (notEditing && count) { me.endEdit(false, modifiedFieldNames); } } else { fields = me.fields; if (fields) { field = fields.get(fieldName); if (field && field.convert) { value = field.convert(value, me); } } currentValue = me.get(fieldName); me[me.persistenceProperty][fieldName] = value; if (field && field.persist && !me.isEqual(currentValue, value)) { if (me.isModified(fieldName)) { if (me.isEqual(modified[fieldName], value)) { // the original value in me.modified equals the new value, so the // field is no longer modified delete modified[fieldName]; // we might have removed the last modified field, so check to see if // there are any modified fields remaining and correct me.dirty: me.dirty = false; for (key in modified) { if (modified.hasOwnProperty(key)){ me.dirty = true; break; } } } } else { me.dirty = true; modified[fieldName] = currentValue; } } if(fieldName === me.idProperty && currentValue !== value) { me.fireEvent('idchanged', me, currentValue, value); } if (!me.editing) { me.afterEdit([fieldName]); } } } }); });
-
13 Mar 2012 1:13 PM #6
The ticket status update hasn't taken for this thread (we're looking into that), but this should be fixed in the nightly builds and in the next public build.
Don Griffin
Ext JS Development Team Lead
Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue
"Use the source, Luke!"
-
1 May 2012 8:23 AM #7
I'm pretty sure this has been fixed in 4.1
-
9 Aug 2012 3:00 AM #8
Confirmed that this error exists in 4.1.1
Confirmed that this error exists in 4.1.1
This error is existing in 4.1.1. Applied the override and then things worked smoothly.
Details -
ExtJs Version 4.1.1
Build date: 2012-07-04 21:23:42 (65ff594cd80b9bad45df640c22cc0adb52c95a7b)
-
9 Aug 2012 9:33 AM #9
Don Griffin
Ext JS Development Team Lead
Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue
"Use the source, Luke!"
-
10 Aug 2012 1:29 PM #10
Hi Don,
My store is created like this -
I'm not using a Model.Code:Ext.define('App.store.Dynamic', { extend : 'Ext.data.Store' ,fields : [] ,proxy : { type : 'rest' ,reader: { root : 'value' ,successProperty : 'success' } } });
Before reconfiguring, I set up the store fields from the 'meta' sent from the server -
store.fields = meta.fields;
And then I fire the reconfigure, as usual, -
grid.reconfigure(store, meta.columns);
Could it be because I don't have a model defined?
Success! Looks like we've fixed this one. According to our records the fix was applied for
EXTJSIV-5136
in
4.1.


Reply With Quote