3

我在 ng-repeat 中遇到双向绑定问题。当您从列表中选择一种颜色时,我希望下面的 $watch 会被触发。

$scope.$watch('favoriteColors', function (newValue) {
    console.log('example-favoriteColors', newValue);
});

我希望在检查时Orange出现。$scope.favoriteColors

示例:http ://plnkr.co/edit/k5SEQw4XFnxriD2I8ZG7?p=preview

directive('checkBox', function () {
    return {
        replace: true,
        restrict: 'E',
        //require: '^ngModel',
        scope: {
            'externalValue': '=ngModel',
            'value': '&'
        },
        template: function (el, attrs) {
            var html =
                '<div class="ngCheckBox">'+
                    '<span ng-class="{checked: isChecked}">' +
                        '<input type="checkbox" ng-model="isChecked"/>'+
                    '</span>'+
                '</div>';
            return html;
        },
        controller: ['$scope', '$timeout', function ($scope, $timeout) {
            var initialized = false;
            console.log($scope.value());
            if (angular.isArray($scope.externalValue)) {
                $scope.isChecked = $scope.externalValue.indexOf($scope.value()) > 0;
            } else {
                $scope.isChecked = !!$scope.externalValue;
            }

            $scope.$watch('isChecked', function (newValue) {
                if (angular.isDefined(newValue)) {
                    //add or remove items if this is an array
                    if (angular.isArray($scope.externalValue)) {
                        var index = $scope.externalValue.indexOf($scope.value());
                        if(index > -1) {
                            $scope.externalValue.splice(index, 1);
                        } else if (initialized) {
                            $scope.externalValue.push($scope.value());
                        }
                    } else {
                        //simple boolean value
                        $scope.externalValue = newValue;
                    }
                    if (initialized)
                        console.log($scope.externalValue);
                }
            });

            $timeout(function () {
                initialized = true;
            });
        }],
        link: function (scope, el, attrs) {

        }
    };
});
4

3 回答 3

2

请查看这个 plunk:http ://plnkr.co/edit/pbHz4ohBPi7iYq6uJI8X?p=preview

有很多变化。他们之中有一些是:

  • 模板不必是函数,因为它是静态的。
  • initialized因此$timeout也不需要 )。
  • 我实现了自己的indexOf功能;对象有可能在意义上不一样==,但在意义上相等x.name === y.name;(虽然我对此有些怀疑)
  • add or remove items if this is an array部分是错误的;您需要根据 的值更新数组isChecked,而不是根据数组中是否已存在该项 ( indexOf)。
  • 初始化favoriteColors为数组,而不是单个对象,要一致,即$scope.favoriteColors = [$scope.colors[1]];
  • (次要)更改时添加了更多描述性日志favoriteColors
  • 用于$watch("favoriteColors", function() {...}, true)观察数组内部的变化(不是true最后一个参数)。
于 2013-10-31T12:00:06.340 回答
0

我看到您正在使用angular-form-ui 的复选框指令

  • 使用$watchCollection链接到文档)而不是$watch观察数组的变化
  • 初始化$scope.favoriteColors为包含应检查值的数组

我已将您的更改恢复为,angular-form-ui.js因为这些更改违反了指令。它们现在与Github (checkbox.js) 上的最新提交中的代码完全相同。只有一件事发生了变化,通过将第二个参数添加到第一行来初始化angular-form-ui模块。[]

这是更新的 plunker:http ://plnkr.co/edit/mlUt46?p=preview

于 2013-11-06T09:24:41.830 回答
0

我认为这是因为您需要引用对象而不是平面数组的属性。当您传递像数组这样的原始数据结构时,它会通过引用传递,因此无法正确传递更新。(马克·拉科克的帖子。

我继续通过破解你的 plunkr 来展示这一点。我更改$scope.favoriteColors = $scope.colors[1];$scope.favoriteColors = {value:$scope.colors[1]};并更改<check-box ng-model="favoriteColors" value="color"><check-box ng-model="favoriteColors.value" value="color">.

Plunkr

您可以在 plunkr 中看到,当您点击复选框时,console.log语句现在在$watch函数下消失。

于 2013-10-28T16:50:20.933 回答