PDA

View Full Version : Ext.data.store.filter() filters current data, not snapshot



jep
31 Jan 2012, 9:53 AM
Sencha Touch version tested:

1.1.1


Platform tested against:

Chrome 16


Description:

In the function Ext.data.Store.filter(), the filter is applied to the data member instead of the snapshot. What happens is that multiple filtering can go wrong if the code used in the filter depends on things outside the actual record.

This also affects other calls which call filter(), such as loadData().


Test Case:



Ext.regModel('User', {
fields: [
{name: 'name', type: 'string'}
]
});

var myStore = new Ext.data.Store({
model: 'User',
data:[
{name:'Joe'},
{name:'Sue'},
{name:'Bob'},
{name:'Jeff'},
{name:'Alice'}
]
});

var firstLetter = 'J';

var filterFn = function (item) {
return item.data.name[0] === firstLetter;
};

new Ext.Application({
name: 'app',
launch: function() {
this.viewport = new Ext.List({
fullscreen:true,
store:myStore,
itemTpl:'<dir>{name}</dir>'
});

myStore.filter(filterFn);

firstLetter = 'S';

myStore.filter();
}
});



Steps to reproduce the problem:

Run the code


The result that was expected:

The list should contain a single "Sue" item.


The result that occurs instead:

The list is empty.


Debugging already done:

I tracked this back to a call in Ext.data.Store.filter():


this.data = this.data.filter(this.filters.items);



Possible fix:


Ext.override(Ext.data.Store, {
filter:function (filters, value) {
if (Ext.isString(filters)) {
filters = {
property: filters,
value : value
};
}

this.filters.addAll(this.decodeFilters(filters));

if (this.remoteFilter) {
//the load function will pick up the new filters and request the filtered data from the proxy
this.load();
} else {
/**
* A pristine (unfiltered) collection of the records in this store. This is used to reinstate
* records when a filter is removed or changed
* @property snapshot
* @type Ext.util.MixedCollection
*/
this.snapshot = this.snapshot || this.data.clone();

//this.data = this.data.filter(this.filters.items); // original line -- jep
this.data = this.snapshot.filter(this.filters.items); // fixed version -- jep

if (this.sortOnFilter && !this.remoteSort) {
this.sort();
} else {
this.fireEvent('datachanged', this);
}
}
}
});

mitchellsimoens
31 Jan 2012, 11:14 AM
Thank you for posting a possible fix for people to use.

jep
31 Jan 2012, 11:28 AM
Of course, whenever possible!

jep
31 Jan 2012, 11:29 AM
In fact, that was the main reason I created the bug, since I didn't find anything in the searches. I'm not as optimistic about 1.x getting many bugfixes since 2.0 is in PR. Heck, 1.x wasn't getting much in the way of bugfixes already. So many major year+ old bugs. But anyway, at least someone can avoid it being a showstopper.