[英]AngularJS directive scope not updating when value changed outside of AngularJS
I am getting started with AngularJS and have a noob problem that I am not sure how to resolve. 我正在开始使用AngularJS,但有一个菜鸟问题,我不确定该如何解决。 I am modifying a value outside of angular (I have put it in the .run section only for demonstration purposes), and then attempting to run $apply so that Angular will notice that the scope needs to be updated.
我正在修改一个超出angular的值(我仅出于演示目的将其放在.run部分中),然后尝试运行$ apply,以便Angular将注意到需要更新范围。
However, in the following code, the {{currentState}} value gets set to "Initial value" and does not ever update to "Second value". 但是,在以下代码中,{{currentState}}值被设置为“初始值”,并且从未更新为“第二值”。
What is the correct approach to get the value to update? 什么是获取价值更新的正确方法?
angular.module("exampleApp", [])
.run(function(userNotificationService) {
userNotificationService.setStatus("Initial value");
setTimeout(function() {
userNotificationService.setStatus("Second value");
}, 1000);
})
.factory('userNotificationService', function($rootScope) {
var currentState = 'Unknown state'; // this should never be displayed
return {
setStatus: function(state) {
$rootScope.$apply(function() {
currentState = state;
});
},
getStatus: function() {
return currentState;
}
};
}).directive('currentState', function(userNotificationService) {
return {
restrict: 'AE',
scope: false, // set to false so that directive scope is used for transcluded expressions
link: function(scope) {
scope.currentState = userNotificationService.getStatus();
}
};
}).controller("defaultCtrl", function ($scope) {
// does nothing
});
And the html is the following: html如下:
<body ng-controller="defaultCtrl">
<div current-state>
current state: {{ currentState }}
</div>
</body>
If your use-case involves a timer, then Angular provides its own timer service called $interval
which wraps the call in a scope.$apply
for you. 如果您的用例涉及一个计时器,那么Angular提供了自己的计时器服务,称为
$interval
,它将调用包装在一个scope.$apply
为您服务。 You should use that instead of setTimeout
. 您应该使用它而不是
setTimeout
。
Now in this case, since you need a one way binding between a service and a value in your scope, you can set up a $watch
in your directive: 现在,在这种情况下,由于您需要在服务和作用域中的值之间进行单向绑定,因此可以在指令中设置
$watch
:
.directive('currentState', function(userNotificationService) {
return {
restrict: 'AE',
scope: false, // set to false so that directive scope is used for transcluded expressions
link: function(scope) {
scope.$watch(function () { return userNotificationService.getStatus(); }, function (newVal) {
scope.currentState = userNotificationService.getStatus();
});
}
};
Ideally how you would do it is by creating this one way (or two way) binding in your controller (which you have left empty). 理想情况下,您将通过在控制器中创建这种单向(或双向)绑定(将其留空)来实现此目的。 The
$scope
you define on the controller will be available to the directive (if you set $scope: false
or $scope: true
), and then you can leave the link
function empty. 您在控制器上定义的
$scope
将可用于该指令(如果将$scope: false
或$scope: true
设置$scope: false
),则可以将link
函数保留为空。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.