在Knockout JS中添加和删除多个过滤器 [英] Adding and removing multiple filters in Knockout JS
问题描述
我希望我的用户不仅能够使用多个过滤器,而且还可以单击一个活动的过滤器将其删除.目前,过滤器一次只能工作一个,除了单击显示全部"之外,没有其他方法可以删除过滤器.我相当确定答案是使用ko.observableArray存储过滤器,根据需要添加或删除它们,并使用filteredPeople遍历它们.不幸的是,我对这种解决方案的尝试未能按计划进行,因此我正在向SO寻求帮助.
I'd like for my users to not only be able to use multiple filters, but to click an active filter to remove it. Right now, filters only work one at a time and there is no way to remove a filter other than clicking "show all". I'm fairly sure the answer is to use a ko.observableArray to store the filters, add or remove them as appropriate, and loop through them with filteredPeople. Unfortunately, my attempts at this solution did not work as planned, so I'm turning towards SO for help.
这里是带有工作代码的JSFiddle: http://jsfiddle.net/rrahlf/EZUEF/6 /
Here is a JSFiddle with working code: http://jsfiddle.net/rrahlf/EZUEF/6/
这是我的淘汰赛代码:
var viewModel = function(){
var self = this;
self.people = ko.observableArray([
{firstName:'James',lastName:'Smith',age:38},
{firstName:'Susan',lastName:'Smith',age:36},
{firstName:'Jeremy',lastName:'Smith',age:10},
{firstName:'Megan',lastName:'Smith',age:7},
{firstName:'James',lastName:'Jones',age:40},
{firstName:'Martha',lastName:'Jones',age:36},
{firstName:'Peggy',lastName:'Jones',age:10}
]);
self.headers = [
{title:'First Name',sortPropertyName:'firstName', asc: true, active: false},
{title:'Last Name',sortPropertyName:'lastName', asc: true, active: false},
{title:'Age',sortPropertyName:'age', asc: true, active: false}
];
self.filters = [
{title:'Show All', filter: null},
{title:'Only Smith', filter: function(item){return item.lastName == 'Smith';}},
{title:'Only Jones', filter: function(item){return item.lastName == 'Jones';}},
{title:'Only Adults', filter: function(item){return item.age >= 18; }}
];
self.activeSort = ko.observable(function(){return 0;}); //set the default sort
self.sort = function(header, event){
//if this header was just clicked a second time
if(header.active) {
header.asc = !header.asc; //toggle the direction of the sort
}
//make sure all other headers are set to inactive
ko.utils.arrayForEach(self.headers, function(item){ item.active = false; } );
//the header that was just clicked is now active
header.active = true;//our now-active header
var prop = header.sortPropertyName;
var ascSort = function(a,b){ return a[prop] < b[prop] ? -1 : a[prop] > b[prop] ? 1 : a[prop] == b[prop] ? 0 : 0; };
var descSort = function(a,b){ return a[prop] > b[prop] ? -1 : a[prop] < b[prop] ? 1 : a[prop] == b[prop] ? 0 : 0; };
var sortFunc = header.asc ? ascSort : descSort;
//store the new active sort function
self.activeSort(sortFunc);
};
self.activeFilter = ko.observable(self.filters[0].filter);//set a default filter
self.setActiveFilter = function(model,event){
self.activeFilter(model.filter);
};
self.filteredPeople = ko.computed(function(){
var result;
if(self.activeFilter()){
result = ko.utils.arrayFilter(self.people(), self.activeFilter());
} else {
result = self.people();
}
return result.sort(self.activeSort());
});
}
ko.applyBindings(new viewModel());
HTML
<div data-bind="foreach: filters">
<input type="button" data-bind="click: $parent.setActiveFilter, value: title"/>
</div>
<br/>
<table>
<thead>
<tr data-bind="foreach: headers">
<th data-bind="click: $parent.sort, text: title"></th>
</tr>
</thead>
<tbody data-bind="foreach: filteredPeople">
<tr>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
<td data-bind="text: age"></td>
</tr>
</tbody>
</table>
推荐答案
只要用户两次单击同一过滤器按钮,只需检查setActiveFilter
函数中的当前过滤器并将其删除:
Just check the current filter in setActiveFilter
function, and drop it, if user click's on the same filter button twice:
self.setActiveFilter = function(model) {
if (self.activeFilter() != model.filter) {
self.activeFilter(model.filter);
} else {
self.activeFilter(self.filters[0].filter);
}
};
这篇关于在Knockout JS中添加和删除多个过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!