在Knockout JS中添加和删除多个过滤器

时间:2014-02-26 18:07:53

标签: jquery sorting knockout.js

我希望我的用户不仅可以使用多个过滤器,还可以点击有效过滤器将其删除。现在,过滤器一次只能工作一个,除了单击“全部显示”之外,无法删除过滤器。我很确定答案是使用ko.observableArray存储过滤器,根据需要添加或删除它们,并使用filteredPeople循环它们。不幸的是,我在这个解决方案上的尝试没有按计划进行,所以我转向求助。

这是一个带有工作代码的JSFiddle: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>

1 个答案:

答案 0 :(得分:1)

只需检查setActiveFilter功能中的当前过滤器,如果用户在同一过滤器按钮上单击两次,则将其删除:

self.setActiveFilter = function(model) {
    if (self.activeFilter() != model.filter) {
        self.activeFilter(model.filter);
    } else {
        self.activeFilter(self.filters[0].filter);
    }
};

Demo