You found a bug! We've classified it as EXTJS-11901 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Sencha Premium Member glopes's Avatar
    Join Date
    Jan 2013
    Location
    Chicago
    Posts
    112
    Vote Rating
    27
    glopes will become famous soon enough glopes will become famous soon enough

      0  

    Default ExtJS 4.2.1 - Removing a record from a grouped store does not remove it from groups

    ExtJS 4.2.1 - Removing a record from a grouped store does not remove it from groups


    Hi,

    Whenever I run a store.remove(record), I can verify that the record has been removed from the store, but I can still see it under store.groups.items[group].records.

    This is breaking my calculations on the GroupingSummary.

    Thanks,

  2. #2
    Sencha Premium Member glopes's Avatar
    Join Date
    Jan 2013
    Location
    Chicago
    Posts
    112
    Vote Rating
    27
    glopes will become famous soon enough glopes will become famous soon enough

      2  

    Default


    I found the error, the store has a method called updateGroupsOnRemove(records) and aparently when you delete just one record it has no length...


    so I created an override like this
    Code:
    remove: function(records, /* private */ isMove, silent) {
            /*
     * Pass the isMove parameter if we know we're going to be re-inserting this record
     */
            isMove = isMove === true;
            
            var me = this,
                sync = false,
                snapshot = me.snapshot,
                data = me.data,
                i = 0,
                length,
                info = [],
                allRecords = [],
                indexes = [],
                item,
                isNotPhantom,
                index,
                record,
                removeRange,
                removeCount,
                fireRemoveEvent = !silent && me.hasListeners.remove;
            // Remove a single record
            if (records.isModel) {
                records = [records];
                length = 1;
            }
            
            // Or remove(myRecord)
            else if (Ext.isIterable(records)) {
                length = records.length;
            }
            
            // Allow remove({start:100: end: 110})
            // Private API used by removeAt to remove multiple, contiguous records
                else if (typeof records === 'object') {
                    removeRange = true;
                    i = records.start;
                    length = records.end + 1;
                    removeCount = length - i;
                }
            
            // Build an array of {record: rec, index: idx} objects to sort into index order.
            // Not necessary if we are removing a contiguous range
            if (!removeRange) {
                for (i = 0; i < length; ++i) {
                    
                    record = records[i];
                    
                    // Encountered a record index
                    if (typeof record == 'number') {
                        index = record;
                        record = data.getAt(index);
                    }
                    // Removing a record instance
                    else {
                        index = me.indexOf(record);
                    }
                    
                    // Check record. If number passed, it may not exist.
                    if (record && index > -1) {
                        info.push({
                            record: record,
                            index: index
                        });
                    }
                    
                    // record guaranteed to be a record now
                    if (snapshot) {
                        snapshot.remove(record);
                    }
                }
                
                // Sort records into ascending order so that removalscan be processed in a deterministic order
                info = Ext.Array.sort(info, function(o1, o2) {
                    var index1 = o1.index,
                        index2 = o2.index;
                    
                    return index1 === o2.index2 ? 0 : (index1 < index2 ? -1 : 1);
                });
                
                // The loop below loops through the info array if not removing contiguous range
                i = 0;
                length = info.length;
            }
            
            // we need to maintain a set of indexes since we're not guaranteed to
            // be removing the records in order
            // Start value of i is calculated!
            for (; i < length; i++) {
                if (removeRange) {
                    record = data.getAt(i);
                    index = i;
                } else {
                    item = info[i];
                    record = item.record;
                    index = item.index;
                }
                
                allRecords.push(record);
                indexes.push(index);
                
                isNotPhantom = record.phantom !== true;
                // don't push phantom records onto removed
                if (!isMove && isNotPhantom) {
                    
                    // Store the index the record was removed from so that rejectChanges can re-insert at the correct place.
                    // The record's index property won't do, as that is the index in the overall dataset when Store is buffered.
                    record.removedFrom = index;
                    me.removed.push(record);
                    
                }
                
                record.unjoin(me);
                
                // Remove using the index, but subtract any intervening removed records which would cause the data
                // array to shuffle up.
                index -= i;
                sync = sync || isNotPhantom;
                
                // If we have not been asked to remove a range we must remove individual records
                // and fire the individual remove event..
                if (!removeRange) {
                    if(me.isGrouped()) {
                        me.updateGroupsOnRemove(record);
                    }                
                    data.removeAt(index);
                    // Only fire individual remove events if not silent, and there are listeners.
                    if (fireRemoveEvent) {
                        me.fireEvent('remove', me, record, index, !!isMove);
                    }
                }
            }
            
            // If there was no listener for the single remove event, remove all records
            // from collection in one call
            if (removeRange) {
                data.removeRange(records.start, removeCount);
            }
            
            if (!silent) {
                me.fireEvent('bulkremove', me, allRecords, indexes, !!isMove);
                me.fireEvent('datachanged', me);
            }
            if (!isMove && me.autoSync && sync && !me.autoSyncSuspended) {
                me.sync();
            }
        }
    Code:
        updateGroupsOnRemove: function(records) {
            var me = this,
                groups = me.groups,
                len = records.length,
                i, groupName, group, rec;
    
    
            if(!len) {
                rec = records;
                groupName = me.getGroupString(rec);
                group = groups.getByKey(groupName);
                console.log(group);
                if (group) {
                    group.remove(rec);
                    if (group.records.length === 0) {
                        groups.remove(group);
                    }    
                }
            } else {
                for (i = 0; i < len; ++i) {
                    rec = records[i];
                    groupName = me.getGroupString(rec);
                    group = groups.getByKey(groupName);
                    console.log(group);
                    if (group) {
                        group.remove(rec);
                        if (group.records.length === 0) {
                            groups.remove(group);
                        }    
                    }
                }
            }

    It is not the most elegant solution but it works.

  3. #3
    Sencha - Support Team
    Join Date
    Feb 2013
    Location
    California
    Posts
    4,082
    Vote Rating
    69
    Gary Schlosberg has a spectacular aura about Gary Schlosberg has a spectacular aura about Gary Schlosberg has a spectacular aura about

      0  

    Default


    Thanks for the report! We have opened a bug in our bug tracker.


    Are you a Sencha products veteran who has wondered what it might be like to work at Sencha? If so, please reach out to our recruiting manager:
    sheryl@sencha.com

  4. #4
    Sencha User Daniil's Avatar
    Join Date
    Jun 2010
    Location
    Saint-Petersburg, Russia
    Posts
    977
    Vote Rating
    113
    Daniil is a name known to all Daniil is a name known to all Daniil is a name known to all Daniil is a name known to all Daniil is a name known to all Daniil is a name known to all

      1  

    Default


    We have faced this problem as well. @glopes, thank you for the fix.
    Ext.NET - ASP.NET for Ext JS
    MVC and WebForms
    Examples | Twitter

Thread Participants: 2