试图从指令内部范围观察外部范围不起作用

时间:2013-07-11 17:37:23

标签: angularjs angularjs-directive angularjs-scope

我在指令中观察范围变量时遇到一些困难。

我有一个带有范围变量的控制器,名为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()更新变量之后一切正常。为什么我需要手动调用此函数?

2 个答案:

答案 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) {
...

}]);