我正在尝试将排序属性(sortProperties
和sortAscending
)与数据列表中的过滤器结合起来。
我有一个ArrayController
和两个动作,一个用于排序,一个用于过滤器。筛选操作在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,output
答案 0 :(得分:1)
您正在更新filters
对象的属性,因此您需要观察正在更改的特定对象属性。
您可以通过明确列出要依赖的属性来执行此操作:
filteredContent: function () {
//...
}.property('arrangedContent', 'filters.id', 'filters.title'),
或使用名为property brace expansion的简写符号。
filteredContent: function () {
//...
}.property('arrangedContent', 'filters.{id,title}'),
更新了JSBin:http://jsbin.com/nuyegowede/1/edit
新的JSBin,filters
为数组: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;
}
}
更新computed属性以使用新的过滤器对象,并监听对数组中每个项目的更改
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