Success! Looks like we've fixed this one. According to our records the fix was applied for EXTJS-5136 in a recent build.
  1. #1
    Sencha - Community Support Team mystix's Avatar
    Join Date
    Mar 2007
    Location
    Singapore
    Posts
    6,236
    Vote Rating
    5
    mystix will become famous soon enough

      0  

    Default [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]);
                }
            }
        }
    });

  2. #2
    Sencha - Community Support Team mystix's Avatar
    Join Date
    Mar 2007
    Location
    Singapore
    Posts
    6,236
    Vote Rating
    5
    mystix will become famous soon enough

      0  

    Default


    * 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.

  3. #3
    Ext JS Premium Member burnnat's Avatar
    Join Date
    Jun 2011
    Posts
    418
    Vote Rating
    61
    burnnat is a jewel in the rough burnnat is a jewel in the rough burnnat is a jewel in the rough burnnat is a jewel in the rough

      0  

    Default


    Just encountered this myself, in 4.1b2. Would sure be nice to have this fixed in Ext.

  4. #4
    Ext JS Premium Member burnnat's Avatar
    Join Date
    Jun 2011
    Posts
    418
    Vote Rating
    61
    burnnat is a jewel in the rough burnnat is a jewel in the rough burnnat is a jewel in the rough burnnat is a jewel in the rough

      0  

    Default


    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.

  5. #5
    Sencha User Izhaki's Avatar
    Join Date
    Apr 2009
    Location
    London
    Posts
    118
    Vote Rating
    13
    Izhaki will become famous soon enough

      0  

    Default


    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]);
                    }
                }
            }
            
        });
        
    });

  6. #6
    Sencha - Ext JS Dev Team dongryphon's Avatar
    Join Date
    Jul 2009
    Location
    Kansas
    Posts
    1,513
    Vote Rating
    176
    dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of

      0  

    Default


    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
    Engineering Manager - Frameworks (Ext JS / Sencha Touch)

    Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue

    "Use the source, Luke!"

  7. #7
    Sencha User Izhaki's Avatar
    Join Date
    Apr 2009
    Location
    London
    Posts
    118
    Vote Rating
    13
    Izhaki will become famous soon enough

      0  

    Default


    I'm pretty sure this has been fixed in 4.1

  8. #8
    Sencha User
    Join Date
    Apr 2007
    Posts
    38
    Vote Rating
    3
    abhijit is on a distinguished road

      0  

    Default 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. #9
    Sencha - Ext JS Dev Team dongryphon's Avatar
    Join Date
    Jul 2009
    Location
    Kansas
    Posts
    1,513
    Vote Rating
    176
    dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of dongryphon has much to be proud of

      0  

    Default


    Quote Originally Posted by abhijit View Post
    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)
    Looking at the code I don't see how this could happen in 4.1.1 - can you post a snippet of what you did and what you see that you did not expect?

    The set method does not even call begin/endEdit any more but only afterEdit and then only if a field was updated.
    Don Griffin
    Engineering Manager - Frameworks (Ext JS / Sencha Touch)

    Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue

    "Use the source, Luke!"

  10. #10
    Sencha User
    Join Date
    Apr 2007
    Posts
    38
    Vote Rating
    3
    abhijit is on a distinguished road

      0  

    Default


    Hi Don,

    My store is created like this -
    Code:
    Ext.define('App.store.Dynamic', {
        extend : 'Ext.data.Store'
       ,fields	: []
       ,proxy : {
            type : 'rest'
           ,reader: {
                root : 'value'
               ,successProperty : 'success'
            }
        }
    });
    I'm not using a Model.

    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?