1

我很确定我做错了什么,因为我对 Angular 的经验很少。可能答案已经在stackoverflow的某个地方,我没有问(谷歌搜索)正确的问题。

我有这个非常简单的指令。它只是一个有四种状态的跨度,我想在每次点击跨度时改变它。每次单击都会将状态向前推进,然后循环返回。每个州都有不同的 CSS 类。我希望每次指令的值更改时父模型上的值都会更改(因此在隔离范围声明中使用“=”,对吗?)。

我对值进行了监视以更改类,以便每次值更改时都会更新css类。

现在,问题是当我单击时,手表会使用 newValue 触发,但随后手表会再次触发 newValue 等于单击前的值。

我认为这与脏检查和与父控制器模型的连接有关,但是,这样做的正确角度方式是什么?和/或有更好、更棱角分明的方式来获得相同的结果?

这里的指令:

.directive('square', function() {
    return {
        restrict: 'E',
        transclude: true,
        scope : {
            value : '=',
        },
        link: function(scope, elm, attrs, ctrl) {

            scope.valueToClass = function(value) {
                var result = 'square-empty';
                    if (value == '1') {
                        result = 'square-temp';
                    } else if (value == '2') {
                        result = 'square-confirmed';
                    } else if (value == '3') {
                        result = 'square-critical';
                    }
                return 'block-'+result;
            }

            scope.$watch('value', function(newValue, oldValue) {
                scope.blockClass = scope.valueToClass(newValue)

            }, true);

        },
        controller: function($scope, $element, $attrs) {
            $scope.changeValue = function() {
                $scope.value = ($scope.value+1) % 4;
            }
        },
        template : '<span class="{{blockClass}}"  ng-click="changeValue();">'+'</span>',
        replace: true
    };
});

这里>>小提琴<<

4

3 回答 3

3

这是因为您在观察 $scope.block 数组的原始值(整数)的变化。

在控制器中试试这个

 $scope.block = [{value: 3}, {value: 2}, {value: 1}, {value: 0}];

然后在视图中:

<square ng-repeat="squareValue in block" value="squareValue.value"></square>

(英语不是我的第一语言,所以很抱歉简短的回答)

于 2013-04-04T11:05:58.947 回答
3

您不应该使用原始值来观察更改,因为由于 javascript 子范围中的原型继承会覆盖父范围值。请参阅非常好的文章,其中解释了所有原因。 https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

于 2013-04-04T11:28:37.427 回答
0

另一个可能对某人有帮助的答案是您需要检查 newVal 是否已更改, newVal 将始终被传入,因此您需要检查它是否不同,即:

$scope.$watch('someProperty', function(newVal, oldVal) {
    if (newVal !== oldVal) {
        // do something
    }
});

我发现这解决了我的 $watch 侦听器过早触发的问题,无论范围属性是否是原始的,即我的属性是一个整数 $scope.menuId。

于 2013-12-05T09:58:02.867 回答