当AngularJS之外的值发生更改时,AngularJS指令范围不会更新

时间:2014-07-10 21:14:40

标签: javascript angularjs

我开始使用AngularJS并遇到一个noob问题,我不知道如何解决。我正在修改一个超出角度的值(我已将它放在.run部分仅用于演示目的),然后尝试运行$ apply,以便Angular注意到范围需要更新。

但是,在以下代码中,{{currentState}}值设置为"初始值"并且永远不会更新为"第二个值"。

获取更新价值的正确方法是什么?

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
});

html如下:

<body ng-controller="defaultCtrl">
    <div current-state>
        current state: {{ currentState }}
    </div>
</body>

1 个答案:

答案 0 :(得分:2)

如果您的用例涉及计时器,那么Angular会提供自己的名为$interval的计时器服务,该服务将呼叫包裹在scope.$apply中。您应该使用它而不是setTimeout

现在在这种情况下,由于您需要在服务和范围内的值之间进行单向绑定,因此您可以在指令中设置$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();
             });
        }
    };

理想情况下,如何在控制器中创建这种单向(或双向)绑定(您已将其留空)。您在控制器上定义的$scope将可用于指令(如果您设置了$scope: false$scope: true),那么您可以将link函数留空。