如何取消选中在 ng-repeat 中过滤的复选框

How to uncheck a checkbox that gets filtered in ng-repeat

我花了好几个小时来解决这个问题,但我似乎无法弄明白,所以想知道你们是否可以提供帮助。

我在 json 文件中有一个对象数组,我正在根据文件中的不同属性制作一个过滤菜单,可以 check/uncheck 以查看过滤结果。我遇到的问题是能够取消选中菜单中由于在当前显示的结果中不可用而隐藏的任何项目。

我这里有一个 plunker 的例子:https://plnkr.co/edit/KZmMiSisA1gKyahG5rHF

来自 plunker 的示例:

$scope.list = [
    { parent : 'fruit', type : 'orange' },
    { parent: 'fruit', type : 'apple' },
    { parent : 'fruit', type : 'kiwi' },
    { parent : 'vegetable', type : 'kale' },
    { parent : 'vegetable', type : 'cabbage' }
];
$scope.filtered = $scope.list;

$scope.selectedType = [];
$scope.selectedParent = [];

$scope.$watch(function () {
    return {
    selectedType: $scope.selectedType,
    selectedParent: $scope.selectedParent,
}
}, function (value) {
      var filterType = {
          parent : $scope.selectedParent,
          type : $scope.selectedType,
      };

      var startFilter = $scope.list;

      for (var i in filterType) {
        startFilter = filter(startFilter, filterType[i], i);
      }

      $scope.filtered = startFilter;

}, true);

基本上,如果有人选择 "fruit",然后选择 "orange",但随后取消选中 "fruit",我希望 "orange" 也取消选中。

我刚刚检查了你的 plunker。底部的代码非常复杂,但我可能可以帮助您处理这些片段。

向 parents 添加 ng-change 属性:

<input type="checkbox" 
       checklist-model="selectedParent"
       checklist-value="key"
       data="{{::key}}" 
       ng-change="checkParent(key, checked)"/>

现在您可以检测控制器中的变化:

$scope.checkParent = function(parent, checked) {
  if (!checked) {
    $scope.list.filter(function(fruit) {
      return fruit.parent === parent;
    }).forEach(function(fruit) {
      $scope.selectedType = $scope.selectedType.filter(function(_selectedType) {
      return _selectedType != fruit.type;
      });
    });
  }
};

Plunkr

请注意,这是低效的,因为它会过滤每个未选择的水果的 Selected 类型,可以使用一些不错的功能工具对其进行重构。

但通常我会尽可能更改控制器,并创建具有以下结构的地图:

{
   parent: {
     name: "fruit"
     selected: false,
     children: [{
       type: "organge"
       selected: false
     }]
     ...
}

通过这种方式,您可以使控制器代码更具可读性。

编辑:

我正在检查你写的两个过滤器。我想不出更好的代码,因为我仍然认为您应该更改数据结构。遍历列表是一个昂贵的过程,并且您的两个过滤器都有两个嵌套的 for 循环。我想不出用你的数据结构摆脱它们的简单方法。

我花了一些时间来重构你的代码,摆脱监视并利用 lodash。查看更新后的Plunk,希望对您有所帮助。

我把这个功能添加到你的 plunker:

 $scope.uncheck = function(key){

  $scope.selectedType.splice(key)
}

致家长:

       <input type="checkbox" checklist-model="selectedParent" checklist-value="key" data="{{::key}}" ng-change="uncheck(key)" />

如果这实际上是您想要完成的,它对我有用。