我正在创建一个分页可观察对象。我用一个集合实例化它,它有一个派生的paginatedList
,稍后我会更新它的主列表(比如我已经过滤了数据)。显然,我希望派生列表能够识别并重新渲染视图,但它并没有。一定不能正确绑定。
Here's a fiddle.
var Pagination = can.Map.extend({
pageNumber: 1,
pageSize: 10,
isFirstPage: can.compute(function() {
return this.attr('pageNumber') === 1;
}),
isLastPage: can.compute(function() {
return this.attr('pageNumber') === this.attr('lastPage');
}),
lastPage: can.compute(function() {
return Math.ceil(this.attr('list').attr('length') / this.attr('pageSize'));
}),
paginatedList: can.compute(function() {
var pgn = this.attr('pageNumber'),
pgs = this.attr('pageSize'),
start = (pgn-1) * pgs,
end = start + pgs;
return this.attr('list').slice(start, end);
}),
prevPage: function() {
if (!this.attr('isFirstPage'))
this.attr('pageNumber', this.pageNumber-1);
},
nextPage: function() {
if (!this.attr('isLastPage'))
this.attr('pageNumber', this.pageNumber+1);
},
toPage: function(pageNumber) {
this.attr('pageNumber', pageNumber);
}
});
var paginated = new Pagination({ list: collection });
...模板看起来像......
<table>
{{#paginated.paginatedList}}
<tr>
....
</tr>
{{/paginated.paginatedList}}
</table>
然后,稍后,用户过滤列表...
paginated.attr('list').replace(collection.filter(function() {
// return filtered collection
}))
但视图不会重新渲染。什么不受约束?
答案 0 :(得分:1)
首先,尝试解释我认为你的例子中发生的事情:
了解can.compute如何确定如何发布/发出它已经发生了变化可能并不明显,但在您的示例中,计算paginatedList
将发出它在任何属性时已更改的事实pageNumber
,pageSize
或list
更改,您可以在计算机中看到使用.attr()
访问器方法访问属性的内容。
can.List中的replace
方法替换列表中的项而不是列表本身,所以
在这个例子中,.attr('list')
访问的属性实际上并没有改变(也没有
pageNumber
或pageSize
),它仍然是列表的相同实例,它只有不同的项目
现在,因此计算出的值不会更新,而后者又不会更新模板。
作为示例的简单/天真修复,您只需替换:
paginated.attr('list').replace(collection.filter(function() {
return Math.random() < 0.5;
}));
带
paginated.attr('list', collection.filter(function() {
return Math.random() < 0.5;
}));
...即替换整个列表,而不仅仅是列表中的项目。
这是改变http://jsfiddle.net/phx1jgq1/1/
的小提琴当然这可能不是您想要的,也许您实际上想要绑定到项目可能更改的列表。
这里的问题是this.attr('list').slice(start, end);
并没有真正绑定到列表中的所有单个项目,而是类似于:
this.attr('list').filter(function(item, index){
return index >= start && index < end;
});
...确实如此,所以你可以直接替换那条线,让它像你期望的那样工作。
这是一个改变的小提琴:http://jsfiddle.net/n2tygdud/1/
当然,如果过滤所有项目感觉不对,您可能需要查看 define plugin ,让您将高级和特定行为映射到can.Maps就像getter,setter和type conversion,并使用它来绑定到列表添加/删除事件并相应地更新计算属性。