我很确定我做错了,因为我对角度的经验不多。 可能答案已经在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
};
});
答案 0 :(得分:3)
这是因为您正在观察$ scope.block数组的原始值(整数)的变化。
在控制器中试试
$scope.block = [{value: 3}, {value: 2}, {value: 1}, {value: 0}];
然后在视图中:
<square ng-repeat="squareValue in block" value="squareValue.value"></square>
(Englsh不是我的第一语言,对于简短的回答很抱歉)
答案 1 :(得分:3)
您不应该使用原始值来观察更改,因为由于javascript中的原型继承,子范围会超出父范围值。请查看非常好的文章,其中解释了所有原因。 https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance
答案 2 :(得分:0)
另一个可能对某人有帮助的答案是,您需要检查newVal是否已更改,newVal将始终传入,因此您需要检查它是否相同,即:
$scope.$watch('someProperty', function(newVal, oldVal) {
if (newVal !== oldVal) {
// do something
}
});
我发现这解决了我的$ watch监听器过早触发的问题,无论scope属性是否是原始的,即我的属性是一个整数$ scope.menuId。