Solefald,肯定有更好的方法来做到这一点。
首先,将一组您自己的“过滤器”对象添加到您的视图模型,以及一个 ko.computed 以提供您过滤的数据。将过滤器按钮绑定到“过滤器”对象数组。像这样的东西:
var viewModel = function(){
var self = this;
self.filters = [
{buttonText:'Button Text', filterKey:'filterKeyOne'},
{buttonText:'Other Button Text', filterKey:'filterKeyTwo'}
];
self.selectedFilterKey = ko.observable('none');
self.setFilter = function(){...}
self.data = ko.observableArray([...]);
self.filteredData = ko.computed(function(){...});
}
并像这样绑定:
<div data-bind="foreach: filters">
<button data-bind="click : $parent.setFilter, text: buttonText"></button>
</div>
<div data-bind="foreach: filteredData">
...
</div>
通过让 Knockout 对过滤器按钮进行点击绑定,您将获得整个过滤器对象作为“runFilter”函数中的第一个参数。然后,您可以像这样实现您的过滤器按钮单击处理程序(本例中的“setFilter”):
self.setFilter = function(filterItem){
self.selectedFilterKey(filterItem.filterKey);
};
通过使“selectedFilterKey”成为可观察对象,您可以将您的过滤数据实现为 ko.computed,当“selectedFilterKey”更改时,它将自动更新 ui,如下所示:
...
self.filteredData = ko.computed(function(){
//pick the right filter function
var filterFunction = filterOne;//assign the default filter function
switch(self.selectedFilterKey()){
case 'filterKeyOne':
filterFunction = self.filterOne;//your first filter
break;
case 'filterKeyTwo':
filterFunction = self.filterTwo;//your second filter
break;
}
return ko.utils.arrayFilter(self.data(), function(item){
//return true if item passes filter
return filterFunction(item);
});
});
...
一种功能方法
如果您想使用更具功能性的编程方法,请尝试在过滤器对象中定义您的过滤器函数。
self.filters = [
{buttonText:'Button Text', filterFunction:function(item){...}},
{buttonText:'Other Button Text', filterFunction:function(item){...}}
];
并存储选定的功能,而不是一个键
self.setFilter = function(filterItem){
self.selectedFilterFunction(filterItem.filterFunction);
};
并跳过 switch 语句
...
self.filteredData = ko.computed(function(){
return ko.utils.arrayFilter(self.data(), function(item){
//return true if item passes filter
return self.selectedFilterFunction()(item);
});
});
...
更多信息
如果您想了解有关这种排序方法的更多信息,可以在我的博客上阅读:http ://ryanrahlf.com/sorting-tables-by-column-header-with-knockout-js/
我希望这有帮助!