如何取消选中以ng-repeat方式过滤的复选框

时间:2016-05-30 18:23:04

标签: angularjs ng-repeat watch angular-filters checklist-model

我一直在摸不着头脑进行数小时的故障排除,我似乎无法弄明白,所以想知道你是否有人可以提供帮助。

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

我在这里有一个有关的例子: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);

基本上,如果有人选择“水果”然后选择“橙色”,然后取消选中“水果”,我也希望“橙色”取消选中。

2 个答案:

答案 0 :(得分:2)

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

向父母添加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

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

但总的来说,如果可能,我会更改控制器,并创建一个具有以下结构的地图:

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

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

编辑:

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

我花了一些时间来重构代码,摆脱手表并使用lodash。检查更新的Plunk,我希望它有所帮助。

答案 1 :(得分:1)

我将此功能添加到你的plunker:

 $scope.uncheck = function(key){

  $scope.selectedType.splice(key)
}

这是给父母的:

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

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