2014-02-26 54 views
0

我希望我的用户不仅可以使用多个过滤器,还可以单击活动过滤器以将其删除。现在,过滤器一次只能工作一次,除了单击“全部显示”以外,无法删除过滤器。我相当肯定答案是使用ko.observableArray存储过滤器,根据需要添加或删除它们,并使用filteredPeople循环它们。不幸的是,我对这个解决方案的尝试没有按计划进行,所以我正在寻求帮助。在Knockout JS中添加和删除多个过滤器

这里是工作的代码的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

查一下setActiveFilter功能当前过滤器,并降它,如果用户点击两次相同的过滤器按钮:

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

Demo

+0

聪明!这解决了这个问题,但仍然存在多个过滤器的问题......是否有办法显示例如史密斯姓氏的成年人? – user1787531

+1

我可以让你在'self.filters'中的每个项目中添加'isSelected:ko.observable()'prop。删除'self.activeFilter',并且在'self.filteredPeople'中只使用'self.filters'和'isSelected'属性。 – alexmac

+0

好主意 - 这有助于消除代码中的一些混乱。公认。 – user1787531

相关问题