我在指令中观察范围变量时遇到一些困难。
我有一个带有范围变量的控制器,名为val:
$scope.val = { name: "hello" };
我有一个使用此值的指令。所以在这个控制器的视图中我有以下几点:
<custom-component custom-attribute="val"></custom-component>
我已经构建了一个具有范围
的指令var myDir = function() {
return {
restrict: 'E',
scope: {
customAttribute: '=customAttribute'
},
link: function(scope, elem, attr) {
scope.$watch('customAttribute', function(val){ console.log(val); }
},
replace: true,
template:'<div class="hello"></div>'
};
}
首次运行应用程序时,手表功能会很好。现在我在控制器中设置超时并执行以下操作:
setTimeout(function(){
console.log("Changed chart type name");
$scope.customAttribute.name="baz";
},5000);
这不会导致监视功能触发!我不确定是什么问题。我也尝试将超时放在指令链接函数中,以防出现一些对象复制问题(低于范围。$ watch):
link: function(scope, elem, attr) {
scope.$watch('customAttribute', function(val){ console.log(val); }
setTimeout(function(){
console.log("Changed chart type name");
scope.customAttribute.name="baz";
},5000);
},
这仍然不起作用!
编辑:
所以我发现如果在我的控制器中我调用$ scope。$ digest()更新变量之后一切正常。为什么我需要手动调用此函数?
答案 0 :(得分:3)
由于您正在使用在角度上下文之外调用的setTimeout,因此您必须调用范围。$ apply,有两种方法可以解决您的问题
1)使用scope.$apply()
link: function(scope, elem, attr) {
scope.$watch('customAttribute', function(val){ console.log(val); }
setTimeout(function(){
console.log("Changed chart type name");
scope.customAttribute.name="baz";
scope.$apply();
},5000);
},
2)以角度$timeout
link: function(scope, elem, attr) {
scope.$watch('customAttribute', function(val){ console.log(val); }
$timeout(function(){
console.log("Changed chart type name");
scope.customAttribute.name="baz";
},5000);
},
答案 1 :(得分:3)
而不是setTimeout
,使用$timeout
,即AngularJS等效项。它使用$ scope。$在内部申请。对于setTimeout
,事情发生在“Angular World”之外,而您的应用程序并不知道它们。
不要忘记将$timeout
注入您的控制器:
.controller('MyCtrl', ['$timeout', function($timeout) {
...
}]);