Angular:$ scope。$观看嵌套集合

时间:2015-09-26 13:08:18

标签: javascript angularjs ng-repeat watch

在我的Angular应用程序中,我有一个复选框列表,它是通过嵌套的ng-repeat生成的,如下所示:

<div ng-repeat="type in boundaryPartners">
    <div class="row">
        <div class="col-xs-12 highlight top-pad">
            <div ng-repeat="partner in type.partners" class="highlight">
                <label class="checkbox-inline">
                    <input type="checkbox" value="partner"
                    ng-model="ids[$parent.$index][$index]"
                    ng-true-value="{{partner}}"
                    ng-false-value="{{undefined}}">
                    <p><span ></span>{{partner.name}}<p>
                </label>
            </div>
        </div>
    </div>
</div>

并在我的控制器中:

$scope.ids = [];

$scope.$watchCollection('ids', function(newVal) {
    for (var i = 0, j = newVal.length; i < j; i++) {

        // Create new participatingPatners tier if it doesn't exist
        if(!$scope.report.participatingPartners[i]) $scope.report.participatingPartners[i] = {};

        // Give it an id
        $scope.report.participatingPartners[i].id = i + 1;

        // Map our values to it
        $scope.report.participatingPartners[i].entities = $.map(newVal[i], function(value, index) {
            return [value];
        });
    }

});

问题是,一旦我添加了每个顶级$scope.$watchCollection中的一个,这个ids就会停止观看,所以如果我从第一个嵌套列表添加一定数量的输入,那么另一个来自第二个列表,我的$scope.report.participatingPartners对象永远不会更新。

我如何$watch ids[$parent.$index][$index]内的更改,确保每当复选框获得票证或未选中时更新我的​​对象?

3 个答案:

答案 0 :(得分:1)

您正在创建一个数组数组:

$scope.ids = [
  [],
  [],
  //...
]

但是使用$watchCollection来监视外部数组的变化,即$scope.ids。这只会在嵌套数组成为不同对象(或第一次创建)时识别更改。

可以使用$scope.$watch("ids", function(){}, true) - true代表“深度观察”,但这会非常浪费,因为这是一项昂贵的检查,将会执行每个摘要周期,是否单击了复选框。

相反,使用ng-change来触发处理程序:

<input type="checkbox" value="partner"
       ng-model="ids[$parent.$index][$index]"
       ng-change="handleCheckboxChanged()">
$scope.handleCheckboxChanged = function(){

  // whatever you wanted to do before in the handler of $watchCollection
}

答案 1 :(得分:0)

$watchCollection$watch类似,因为它检查物理对象引用,但更进了一步;它也深入一级并对这些属性进行参考检查。

您需要使用$watch,但将objectEquality标志设置为true。这将告诉$watch执行深度引用检查。根据所观看项目的深度,这会严重影响性能。

$watch(watchExpression, listener, [objectEquality]);

答案 2 :(得分:-1)

你能尝试观察对象的平等吗?

$scope.$watchCollection('ids', function(newVal) {

}, true);