2015-06-22 107 views
3

曾經有一段時間,這是行得通的,但不知何故,它被打破。我希望能夠使用ng-repeat生成複選框,根據存儲的數據獲取所需的複選框,並使用這些複選框過濾生成的表。如何使用帶Angularjs的ng-repeat複選框過濾表格

此外,我不希望相同的值複選框被重複。

我用代碼做了一個plnkr。

<div class="row"> 
    <label data-ng-repeat="x in projects"> 
     <input 
     type="checkbox" 
     data-ng-true-value="{{x.b}}" 
     data-ng-false-value='' 
     ng-model="quer[queryBy]" /> 
     {{x.b}} 
    </label> 
</div> 

http://plnkr.co/edit/RBjSNweUskAtLUH3Ss6r?p=preview

因此,在總結。

  1. 複選框要過濾Ref

  2. 複選框是唯一的。

  3. 複選框將基於ng-repeat使用Ref

回答

2

好吧,這是如何做到這一點。

首先,讓我們添加幾個CSS的線在你確保所有複選框都可見:

<style> 
    .row { margin-left: 0px } 
    input[type=checkbox] { margin-left: 30px; } 
</style> 

接下來,將下列行添加到您的控制器:

app.filter('unique', function() { 

    return function (arr, field) { 
    var o = {}, i, l = arr.length, r = []; 
    for(i=0; i<l;i+=1) { 
     o[arr[i][field]] = arr[i]; 
    } 
    for(i in o) { 
     r.push(o[i]); 
    } 
    return r; 
    }; 
}) 

    app.controller("maincontroller",function($scope){ 
    $scope.query = {}; 
    $scope.quer = {}; 
    $scope.queryBy = '$'; 
    $scope.isCollapsed = true; 
    $scope.selectedRefs = []; 

    $scope.myFilter = function (item) { 
    var idx = $scope.selectedRefs.indexOf(item.b); 
    return idx != -1; 
    }; 

    $scope.toggleSelection = function toggleSelection(id) { 
    var idx = $scope.selectedRefs.indexOf(id); 
    if (idx > -1) { 
     $scope.selectedRefs.splice(idx, 1); 
    } 
    else { 
     $scope.selectedRefs.push(id); 
    } 
    }; 

唷。

由於某些原因,您的Plunkr版本AngularJS未識別unique屬性,因此我向控制器添加了一個屬性。

最後,你的HTML改成這樣:

<div class="row"> 
    <label data-ng-repeat="x in projects | unique:'b' | orderBy:'b'" > 
     <input 
     id="x.b" 
     type="checkbox" 
     ng-click="toggleSelection(x.b)" 
     ng-init="selectedRefs.push(x.b)" 
     ng-checked="selectedRefs.indexOf(x.b) > -1" /> 
     {{x.b}} 
    </label> 
</div> 

...和你的NG-重複這個...

<tr ng-click="isCollapsed = !isCollapsed" ng-repeat-start="x in projects | filter:myFilter | orderBy:orderProp"> 

如果你想知道這是如何工作的,添加這些行:

<div style="margin:10px 10px 30px 10px"> 
    <pre>{{ selectedRefs }} </pre> 
</div> 

我喜歡這個竅門:你可以看到我們的「selectedRefs」陣列的確切內容,看它在我們勾選/取消勾選我們的複選框時更改。這在開發/測試我們的綁定時確實有幫助!

Binding

正如你可以看到,這些變化使用新unique功能,從您的project陣列得到您的不同值的列表,並在第一次加載頁面,我們就將所有的值到我們的新「 selectedRefs「陣列。

["123","321","456","654","789","987"] 

然後,當您勾選/取消勾選複選框時,我們從該列表中添加/刪除該項目。

最後,我們在ng-repeat中使用該過濾器。

ng-repeat-start="x in projects | filter:myFilter | orderBy:orderProp" 

工作完成!

更新

如果你想與所有的複選框取消選中開始關閉,那麼它是一個簡單的變化。只是刪除此行...

ng-init="selectedRefs.push(x.b)" 

..和改變myFilter功能最初顯示所有項目..

$scope.myFilter = function (item) { 
    if ($scope.selectedRefs.length == 0) 
     return true; 

    var idx = $scope.selectedRefs.indexOf(item.b); 
    return idx != -1; 
}; 

,並添加了「全部清除」按鈕,只需添加一個按鈕,您的形式,它在你的AngularJS控制器這樣調用一個函數..

$scope.clearAll = function() { 
    $scope.selectedRefs = []; 
}; 

(我還沒有測試,雖然這些建議。)

+0

親愛的主,什麼CSS屬性設置一個poointer ** **這隻手?我現在想知道! :D –

+0

這是Windows 10中新的默認光標。他們可能會選擇在發佈之前更改它。 ;-) –

+0

哦,該死的恥辱;) –

2

ng-false-value指令需要一個值集。嘗試ng-false-value='false'ng-false-value='null'(事實上,如果它只是一個虛假值,而不是具體的東西,比如一個字符串或特定數字,你可以完全跳過這一個)。

正如您在評論中指出的那樣,在選中並清除複選框後,所有行都被過濾掉。發生這種情況是因爲取消選中複選框會將其值設置爲false,並且這與您實體的值不一致(正如您可能知道的,只是將其用於其他人)。

因此,您最終需要將此值設置爲空字符串。這將是方式:

$scope.$watch('quer.$', function() { 
    if ($scope.quer.$ === false) { 
    $scope.quer.$ = ''; 
    } 
}); 
+0

這是一個部分修復。謝謝您的幫助。問題在於,在這樣做時,當您取消選擇複選框並且不能選擇多個表格數據時,將不會重新顯示列。對此有何想法? – TheLimeTrees

+0

沒錯。我馬上更新答案。 –