2013-06-20 28 views
1

我與顯示的記錄列表與AngularJS像這樣的任務:AngularJS獨特的過濾網,然後更新所有記錄

$scope.colours = [ 
    {id:'1', name: 'red', active: true }, 
    {id:'2', name: 'blue', active: false }, 
    {id:'3', name: 'green', active: true }, 
    {id:'4', name: 'red', active: false } 
]; 

,並給用戶顯示/按類別通過複選框隱藏它們(的能力或者以示例顏色)他們坐下。所以我已經採集了數據並使用Angular-UI Unique過濾器顯示了一些複選框,但是當我切換「紅色」類別時,我想要切換所有具有「紅色」值的記錄。

我猜我需要通過記錄循環,並手動執行復選框更改是否有更多的角度的方式來做到這一點?

即使使用Angular Filters來過濾大數據集的ng-repeat結果,這甚至是一個很好的實踐嗎?

見小提琴http://jsfiddle.net/sjmcpherso/QXk9E/

問候

+0

預定義顏色還是取決於從服務器發送的數據? – Chandermani

回答

1

你可以使用排序由多個值的自定義過濾器。這將允許您從所有數據中刪除active屬性。讓我們把它manyToMany,並將它需要三個參數:

  1. 對象的數組排序
  2. 一個字符串,指定由
  3. 布爾屬性,它的鍵關聯的對象哈希排序哪個屬性對這些對象到可能的財產價值。如果排序屬性應包含與該鍵匹配的結果,則任何給定屬性的值將爲true

這裏是過濾器會是什麼樣子:

.filter('manyToMany',function(){ 
    return function(arrInput,strProperty,objMany){ 
     var arrFiltered = []; 
     for(var i=0,max=arrInput.length;i<max;i++){ 
      if(objMany[arrInput[i][strProperty]] === true){ 
       arrFiltered.push(arrInput[i]); 
      } 
     }; 
     return arrFiltered; 
    } 
}); 

然後創建範圍的新對象將被用於objMany

$scope.activeColors = {}; 

而在你的HTML,讓您的複選框根據來自獨特中繼器的顏色名稱在該對象上設置值:

<input type="checkbox" ng-model="activeColors[colour.name]" />{{colour.name}} 

,並使用過濾器,如:

<div ng-repeat="colour in colours | manyToMany:'name':activeColors">{{colour}}</div> 

Here is a fiddle

+0

是的,這工作得很好,謝謝你,並且很少有代碼,雖然我很想知道爲什麼manyToMany過濾器在切換複選框時會運行兩次,想法? Heres小提琴http://jsfiddle.net/sjmcpherso/CGeg5/ – sjm

+0

這與Angular的'$ digest'循環在內部工作的方式有關。這有些複雜,但是每當'$ rootScope'上有一個'$ digest'時,就會檢查它和它的所有子範圍的觀察者。如果在該過程中設置了新值(通常是過濾器),則會再次檢查它們以確保模型已穩定。有關更多信息,請參閱[此鏈接](http://docs.angularjs.org/guide/concepts#runtime)。 – sh0ber

+0

好的,非常感謝你一直關注過濾器 – sjm

0

首先,你的模型不正確。您需要的是用戶根據條件篩選的項目列表 - 在本例中爲顏色。

在這種情況下,您不應該將active屬性放在每個對象上。相反,你應該做的是:

步驟1
定義模型:

$scope.colors = [ 
    { 
     id: 1, 
     name: "red" 
    }, 
    { 
     id: 2, 
     name: "blue" 
    }, 
    { 
     id: 3, 
     name: "green" 
    }, 
    { 
     id: 4, 
     name: "red" 
    } 
]; 

請注意,我沒有添加active屬性爲每個對象呢。

步驟2
接下來,定義用於跟蹤的有源濾波器的另一種模式:

$scope.activeFilters = []; 

最初,這將是空的,但它條目將被添加/移除此取決於選擇每個濾波器的狀態。

步驟3 然後,您有一個功能,將通知如果該複選框被激活或不

$scope.isChecked = function (item) { 
    return $scope.activeFilters.indexOf(item) !== -1; 
}; 

步驟4
您然後定義將添加/移除過濾器的項目的功能:

$scope.toggleFilter = function (filterItem) { 
    //Check if the filter item already exists in the list of active filters 
    if ($scope.activeFilters.indexOf(filterItem) !== -1) { 
     //Yes, the filter item already exists. 
     //Since we are in toggle mode, we remove the item from the active filters 
     $scope.activeFilters.splice($scope.activeFilters.indexOf(filterItem), 1); 
    } else { 
     //No entry does not exist. 
     //Since we are in toggle mode, we add the entry to the list 
     $scope.activeFilters.push(filterItem); 
    } 
}; 

每次任何複選框設置/取消設置,您可以調用此函數。

步驟5
接下來,定義,其基於所述有源濾波器的濾波器數據的功能:

$scope.filterData = function() { 
    //This will be the model that will be used to display the final or 
    //filtered data 
    //Reset it each time this is called 
    $scope.filteredColors = []; 

    //If there are no active filters, show all the colors 
    if ($scope.activeFilters.length === 0) { 
     $scope.filteredColors = $scope.colors; 
    } else { 
     for (var i = 0; i < $scope.colors.length; i++) { 
      //Check if the color name is requested in the active filter 
      if ($scope.activeFilters.indexOf($scope.colors[i].name) !== -1) { 
       //The color has been actively set in the filter. Display it 
       $scope.filteredColors.push($scope.colors[i]); 
      } 
     } 
    } 
}; 

//When the controller is initialized, we need to call the above function once to 
//get the colors to display. Since no filters are active initially, all colors 
//will be shown 
$scope.filterData(); 

步驟6
每次有源濾波器發生變化,則需要重新計算顏色以顯示 - 一個簡單的手錶就足夠了

$scope.$watch('activeFilters.length', function() { 
    //Check for invalid values 
    if ($scope.activeFilters === null || $scope.activeFilters === undefined) { 
     //Nothing to do 
     return; 
    } else { 
     //Re-calculate the colors to display 
     $scope.filterData(); 
    } 
}); 

因此,每次設置/重置過濾器時,將重新計算要顯示的顏色列表。

步驟7
現在需要將包含獨特的色彩模式 - 用於過濾

$scope.uniqueColors = []; 

for (var j = 0; j < $scope.colors.length; j++) { 
    if ($scope.uniqueColors.indexOf($scope.colors[j].name) === -1) { 
     //The color does not exist. Add it 
     $scope.uniqueColors.push($scope.colors[j].name); 
    } 
} 

最後一步
的觀點 - 基於模型和功能,我們已經定義此前,您現在需要相應地定義您的視圖。編輯:Here是一個相同的小提琴。

+0

令人難以置信的完整和不錯的答案。然而,簡單地切換一個過濾器似乎有點長(除非我誤解了這個問題)。 – Chris