2014-02-26 48 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

相關問題