我正在尝试将排序属性(sortProperties
和sortAscending
)与数据列表上的筛选器相结合。
我有一个ArrayController
和两个操作,一个用于排序,另一个用于筛选。Filter操作设置filters
对象的属性,但不重新计算依赖于filters
的属性。
相关控制器代码:
App.PostsController = Ember.ArrayController.extend({
filters: Ember.Object.create({}),
filteredContent: function () {
var ret = this.get('arrangedContent');
Object.keys(this.filters).forEach(function (name) {
ret = ret.filter(this.filters.get(name));
}, this);
return ret;
// I expect this to cause `filteredContent` to depend on `filters` property
}.property('arrangedContent', 'filters'),
actions: {
sort: function(property, isSorted) {
this.set('sortProperties', [property]);
if (isSorted) {
this.toggleProperty('sortAscending');
} else {
this.set('sortAscending', true);
}
},
filter: function (property, value) {
var filters = this.get('filters');
switch (property) {
case 'id':
// I expect that call to `set` would trigger `filteredContent` property update
filters.get('id') || filters.set('id', function (post) {
return post.get('id') < value;
});
break;
case 'title':
filters.get('title') || filters.set('title', function (post) {
return post.get('title').indexOf(value) !== -1;
});
break;
}
}
}
});
所以,我的问题是为什么filters.set()
不导致filteredContent
函数运行?
所有代码都在这里——http://jsbin.com/silun/7/edit?html,js,输出
您正在更新filters
对象的属性,因此需要观察正在更改的特定对象属性。
您可以通过明确列出要依赖的属性来做到这一点:
filteredContent: function () {
//...
}.property('arrangedContent', 'filters.id', 'filters.title'),
或者通过使用称为属性大括号展开的简写表示法。
filteredContent: function () {
//...
}.property('arrangedContent', 'filters.{id,title}'),
更新的JSBin:http://jsbin.com/nuyegowede/1/edit
更新
以filters
为数组的新JSBin:http://jsbin.com/yayihazoza/1/edit
如果您希望在不更新计算属性的情况下使用无限制的筛选器属性,则可以使用configure filters
作为数组而不是对象。这可以让你使用Ember的数组观察器功能(@each)在数组更改时自动更新过滤。
filters
现在是一个过滤器对象的数组,其形式如下:
{
name: 'name-of-filter',
filter: function(){
// implementation of filter here
}
}
更新filter
,将过滤对象推送到filters
数组:
filter: function (property, value) {
var filters = this.get('filters');
console.log("filter", property, value);
switch (property) {
case 'id':
if (filters.findBy('name', 'id') === undefined) {
filters.pushObject({
name: 'id',
filter: function (post) {
return (post.get('id') < value);
}
});
}
break;
case 'title':
if (filters.findBy('name', 'title') === undefined) {
filters.pushObject({
name: 'title',
filter: function (post) {
return post.get('title').indexOf(value) !== -1;
}
});
}
break;
}
}
更新计算的属性以使用新的过滤器对象,并侦听数组中每个项目的更改
filteredContent: function () {
var ret = this.get('arrangedContent');
var filters = this.get('filters');
filters.forEach(function (filterObj) {
ret = ret.filter(filterObj.filter);
}, this);
return ret;
}.property('arrangedContent', 'filters.@each'), // <-- notice the new @each