【问题标题】:Trying to watch outer scope from inner scope in directive not working试图在指令中从内部范围观察外部范围不起作用
【发布时间】:2013-07-10 02:40:15
【问题描述】:

我在从指令中查看范围变量时遇到了一些困难。

我有一个控制器,其范围变量名为 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);

这不会导致手表功能触发!我不确定问题是什么。我还尝试将超时放在指令链接函数中,以防出现一些对象复制问题(在 scope.$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() 一切正常。为什么我需要手动调用这个函数?

【问题讨论】:

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

由于您使用的是在角度上下文之外调用的 setTimeout,因此您必须调用 scope.$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);
},

【讨论】:

    【解决方案2】:

    使用 $timeout 代替 setTimeout,这是 AngularJS 的等效项。它在内部使用 $scope.$apply。使用setTimeout,事情发生在“Angular World”之外,而您的应用程序不知道它们。

    不要忘记将$timeout 注入您的控制器:

    .controller('MyCtrl', ['$timeout', function($timeout) {
    ...
    
    }]);
    

    【讨论】:

      猜你喜欢
      • 2016-06-23
      • 1970-01-01
      • 2021-08-18
      • 2014-07-13
      • 1970-01-01
      • 2011-04-25
      • 1970-01-01
      • 2013-09-18
      • 1970-01-01
      相关资源
      最近更新 更多