【问题标题】:How can you iterate through ng-models within an ng-repeat in an angular controller?如何在角度控制器中的 ng-repeat 中迭代 ng-models?
【发布时间】:2016-01-28 14:17:54
【问题描述】:

我对网络开发很陌生,并且尝试了角度,所以可能会有很多错误.. 基本上我在 ng-repeat 中有一个 ng-repeat,我需要在父级重复中的复选框的子级重复中设置一个模型变量。 我不知道如何从父级访问子级中的模型。我试过给出一个 [$index] 但它不起作用。

这是我的 HTML。我有一个父复选框,它应该更改子复选框 onclick 的 clicked 布尔变量。

<li ng-repeat="set in wordlistSets" ng-controller="setController">

<div class="parentSelector">
<span class="selectorLeft">
    <p> blah </p>
</span>

<span class="selectorRight">
    <input type="checkbox" name="sets" ng-click="selectAll()">
</span>
</div>

<div  ng-repeat="wordlist in set.content"  ng-click="checked[parent.$index][$index] = !checked[parent.$index][$index]">
<span class="selectorLeft">
    <p>more blah</p><br>
    <p>extra blah</p>
</span>

<span class="selectorRight">
    <input type="checkbox" name="wordLists" ng-click="checked[parent.$index][$index] = !checked[parent.$index][$index]" ng-model="checked[parent.$index][$index]">

</span>
</div>

“SelectAll()”函数应该遍历单词列表并相应地切换选中的变量。我不能使用 angulars ng-checked,因为我需要它来切换并且始终不具有与父复选框相同的状态,因为它也可以通过在 div 本身上单击来设置。

这里是控制器。

myApp.controller("setController", function MyController($scope) {
$scope.parentChecked = false;

$scope.selectAll = function() {
    for (var i = 0; i < $scope.set.content; i++) {
        if ($scope.parentChecked) {
            $scope.checked[$scope.index][i] = true;
        } else {
            $scope.checked[$scope.index][i] = false;
        }
    }
}

这是一张供参考的图片。单击粉红色选择器或黑色父选择器应勾选复选框。 Picture of page setup

提前感谢您的帮助! :D

【问题讨论】:

  • 对于每个单独的复选框,使用ng-change 调用控制器函数来迭代$scope.checked 以查看是否需要检查父级。少量数据样本将有助于解决问题,因此可以由其他人进行测试。更好的是,如果您可以将其复制到 plunker 演示,并提供一些数据。真的不需要任何CSS

标签: angularjs checkbox controller ng-repeat angular-ngmodel


【解决方案1】:

感谢上面的评论,我在玩了一会儿后让它完美地工作。生病在这里发布我的解决方案:

一些注意事项。 array.splice 没有按照上面用户发布的方式工作,它应该采用两个变量:array.splice(index, numOfThingToRemove);如果只给出要删除的项目的索引,它将删除该项目以及数组中该项目之后的所有项目。

这里是控制器代码:

$scope.parentChecked = false;
$scope.checkedWordlists = [];

$scope.selectAll = function(wordlists) {m
    //toggle parent
    if ($scope.parentChecked == false) {
        $scope.parentChecked = true;
    } else {
        $scope.parentChecked = false;
    }

    wordlists.forEach(function(wordlist) {
        $scope.setChild(wordlist, $scope.parentChecked);
    });
};

$scope.toggleCheckbox = function(wordlist) {
    var index = $scope.checkedWordlists.indexOf(wordlist);

    if (index > -1) {//is in array
        $scope.checkedWordlists.splice(index, 1);//remove from array
    } else {
        $scope.checkedWordlists.push(wordlist);//add to array
    }
};

$scope.setChild = function(wordlist, parentChecked) {
    var index = $scope.checkedWordlists.indexOf(wordlist);

    if (parentChecked && index <= -1) {//is not in array
        $scope.checkedWordlists.push(wordlist);//add to array
    } else if (!parentChecked && index > -1) {//is in array
        $scope.checkedWordlists.splice(index, 1);//remove from array
    }
};

和html:

<li ng-repeat="set in wordlistSets" ng-controller="setController">

<div class="parentSelector">
<span class="selectorLeft">
    <p> blah </p>
</span>

<span class="selectorRight">
    <input type="checkbox" name="sets" ng-click="selectAll(set.content)" ng-checked="parentChecked">
</span>
</div>

<div  ng-repeat="wordlist in set.content"  ng-click="toggleCheckbox(wordlist)">
<span class="selectorLeft">
    <p>more blah</p><br>
    <p>extra blah</p>
</span>

<span class="selectorRight">
    <input type="checkbox" name="wordLists"  ng-checked="checkedWordlists.indexOf(wordlist)> -1">

</span>
</div>

非常感谢大家的帮助! :3

【讨论】:

  • 感谢您指出 array.splice 和 array.some(而不是 .any)中的语法错误。很高兴你成功了。
【解决方案2】:

我假设您需要孩子们的复选框来独立工作,对吗?在这种情况下,最好的办法是保留一个 checkedWordlists 数组。

$scope.checkedWordlists = [];

$scope.toggleWordlist = function(wordlist) {
   var idx = $scope.checkedWordlists.indexOf(wordlist);
   if (idx>-1) {
      $scope.checkedWordlists.splice(idx);
   } else {
      $scope.checkedWordlists.push(wordlist);
   }
}

在你看来,

<div  ng-repeat="wordlist in set.content"  ng-click="toggleWordlist(wordlist)">
<span class="selectorLeft">
    <p>more blah</p><br>
    <p>extra blah</p>
</span>

<span class="selectorRight">
    <input type="checkbox" name="wordLists" 
           ng-click="toggleWordlist(wordlist)" 
           ng-checked="checkedWordlists.indexOf(wordlist)>-1">
</span>

最后,处理父复选框:

$scope.toggleAll = function(wordlists) {
    var allToggled = $scope.allToggled()
    wordlists.forEach(function(wordlist) {
       if (allToggled == ($scope.checkedWordlists.indexOf(wordlist)>-1) {
           $scope.toggleWordlist(wordList);
       }
    })  
}
$scope.allToggled = function(wordlists) {
    var untoggledExist = wordlists.any(fucntion(wordlist) {
        return $scope.checkedWordlists.indexOf(wordlist) = -1
    });
    return !untoggledExist;
}

还有html:

<span class="selectorRight">
    <input type="checkbox" name="sets" 
              ng-click="toggleAll(set.content)"
              ng-checked="allToggled(set.content)">
</span>

这应该完成大部分工作。我没有对此进行测试,但如果你想在上面包含一个数据集,我们可以创建一个 fiddle 以确保它有效。

希望对你有帮助

【讨论】:

  • 谢谢!这正是我所追求的!在这种情况下,我不知道如何使用 forEach 循环或将单词列表添加到数组中。虽然我无法弄清楚 wordlists.any 是什么,javasript 也无法弄清楚。无论如何,我可以使用稍微不同的代码 :)
  • 抱歉,应该是 'wordlists.some()'。我总是认为它是“任何”,然后在我得到错误后需要更改代码:-)。我很高兴它有帮助。祝你好运!
猜你喜欢
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多