2015-06-22 67 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

没错。我马上更新答案。 –