简体   繁体   English

如何使用Angularjs的ng-repeat复选框过滤表格

[英]How to filter through a table using ng-repeat checkboxes with Angularjs

Once upon a time this was working but somehow it's broken. 曾几何时,这是有效的,但不知怎的,它已经坏了。 I want to be able to produce checkboxes using ng-repeat to get as many checkboxes as required based on stored data and use these to filter through a table produced. 我希望能够使用ng-repeat生成复选框,以根据存储的数据获取所需数量的复选框,并使用这些复选框来筛选生成的表格。

Additionally I don't want identical values for the checkboxes to be repeated. 另外,我不希望重复复选框的相同值。

I have made a plnkr with the code. 我用代码制作了一个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 http://plnkr.co/edit/RBjSNweUskAtLUH3Ss6r?p=preview

So in summary. 所以总结一下。

  1. Checkboxes to filter Ref . 复选框以过滤Ref

  2. Checkboxes to be unique. 复选框是唯一的。

  3. Checkboxes to be made based off ng-repeat using Ref . 使用Ref 。基于ng-repeat制作复选框。

ng-false-value directive needs a value set. ng-false-value指令需要一个值集。 Try ng-false-value='false' or ng-false-value='null' (in fact you can skip this one entirely if it has to just be a falsy value and not something concrete, like a string or certain number). 尝试ng-false-value='false'ng-false-value='null' (事实上​​,如果它只是一个假值而不是具体的东西,比如字符串或某个数字,你可以完全跳过这个) 。

As you've pointed out in the comments, after selecting and then clearing the checkboxes, all rows are filtered out. 正如您在评论中指出的那样,在选中然后清除复选框后,所有行都会被过滤掉。 It happens because unchecking the checkbox will set its value to false, and this does not agree with your entities' values (as you probably know, just stating it for others). 这是因为取消选中该复选框会将其值设置为false,这与您的实体的值不一致(您可能知道,只是为其他人说明)。

Therefore you do need to set this value to empty string in the end. 因此,您需要在最后将此值设置为空字符串。 That'd be the way: 那是这样的:

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

Okay, here's how to do it. 好的,这是怎么做的。

First, let's add a couple of lines of CSS in your to make sure all the checkboxes are visible: 首先,让我们添加几行CSS,以确保所有复选框都可见:

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

Next, add the following lines to your controller: 接下来,将以下行添加到您的控制器:

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);
    }
  };

Phew. 唷。

For some reason, your Plunkr's version of AngularJS didn't recognise the unique attribute, so I added one to your controller. 出于某种原因,您的Plunkr版本的AngularJS无法识别unique属性,因此我在控制器中添加了一个。

Finally, change your html to this: 最后,将你的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>

... and your ng-repeat to this... ...和你的重复...

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

If you're interested in knowing how this works, add these lines: 如果您有兴趣了解其工作原理,请添加以下行:

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

I love this trick: you can see the exact contents of our " selectedRefs " array, and see it change as we tick/untick our checkboxes. 我喜欢这个技巧:你可以看到我们的“ selectedRefs ”数组的确切内容,并在我们勾选/取消选中复选框时看到它的变化。 This really helps when developing/testing our bindings! 这在开发/测试我们的绑定时非常有用!

捆绑

As you can see, these changes use the new unique function to get your list of distinct values from your project array, and when the page first loads, we push all of the values into our new " selectedRefs " array. 如您所见,这些更改使用新的unique函数从project数组中获取不同值的列表,当页面首次加载时,我们将所有值都推送到新的“ selectedRefs ”数组中。

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

Then, as you tick/untick the checkboxes, we add/remove that item from this list. 然后,当您勾选/取消勾选复选框时,我们会在此列表中添加/删除该项目。

Finally, we use that filter in the ng-repeat . 最后,我们在ng-repeat使用该过滤器。

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

Job done ! 任务完成 !

Update 更新

If you wanted to start off with all checkboxes unticked , then it's a simple change. 如果您想从未选中的所有复选框开始 ,那么这是一个简单的更改。 Just remove this line... 只需删除此行...

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

..and change the myFilter function to show all items initially.. ..并更改myFilter函数以最初显示所有项目..

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

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

And to add a "Clear all" button, simply add a button to your form which calls a function in your AngularJS controller like this.. 要添加一个“全部清除”按钮,只需在表单中添加一个按钮,调用AngularJS控制器中的函数,就像这样。

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

(I haven't tested these suggestions though.) (虽然我没有测试过这些建议。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM