1

ディレクティブ内からスコープ変数を監視するのに苦労しています。

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() を呼び出すと、すべてが機能することがわかりました。この関数を手動で呼び出す必要があるのはなぜですか?

4

2 に答える 2

3

angularコンテキストの外で呼び出されるsetTimeoutを使用しているため、scope.$applyを呼び出す必要があるため、問題を解決するには2つの方法があります

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) 関数を angular でラップする$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);
},
于 2013-07-11T17:43:52.307 に答える