我正在尝试将排序属性(sortProperties
和 sortAscending
)与数据列表上的过滤器结合起来。
我有一个 ArrayController 和两个操作,一个用于排序,一个用于过滤器。过滤器操作在 filters
对象上设置属性,但依赖于 filters
的属性不会重新计算。
相关 Controller 代码:
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
最佳答案
您正在更新 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
如果您想要无限的过滤器属性而不更新计算属性,您可以使用配置过滤器作为数组而不是对象。这使您可以使用 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
关于javascript - Ember Controller 计算属性(对象类型)更新不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26793012/