web-dev-qa-db-ja.com

分離スコープを使用した内部ディレクティブからの$ watch ngModel

リンク関数内からモデル値を監視しようとしています。

scope.$watch(attrs.ngModel, function() {
       console.log("Changed"); 
    });

コントローラー内のモデル値を変更しても、$ watch関数はトリガーされません。

$scope.myModel = "ACT";

$timeout(function() {
   $scope.myModel = "TOTALS"; 
}, 2000);

フィドル: http://jsfiddle.net/dkrotts/BtrZH/4/

ここで何が欠けていますか?

54
Dustin

問題は、あなたが$watching attrs.ngModelこれは「myModel」と同じです。スコープに「myModel」がバインドされていません。あなたはしたい $watch "型"。それはあなたのディレクティブのスコープにバインドされているものです。 http://jsfiddle.net/BtrZH/5/ を参照してください

31
dnc253

監視している$ modelValueを返す関数を監視する必要があります。

次のコードは基本的な例を示しています。

app.directive('myDirective', function (){
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
           scope.$watch(function () {
              return ngModel.$modelValue;
           }, function(newValue) {
               console.log(newValue);
           });
        }
     };
});

ここにプランカーがあります 実行中の同じアイデアの。

149
Ben Lesh

これを行う適切な方法は次のとおりです。

app.directive('myDirective', function () {
  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {

        ngModel.$render = function () {
            var newValue = ngModel.$viewValue;
            console.log(newValue)
        };

    }
  };
});
20
Emmanuel

これを行う別の方法を次に示します。

app.directive('myDirective', function (){
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
           attrs.$observe('ngModel', function(value){ // Got ng-model bind path here
              scope.$watch(value,function(newValue){ // Watch given path for changes
                  console.log(newValue);  
              });
           });
        }
    };
});

そのようにすると、そのようなバインドで値の変更を聞くことができます

8
user2978730

これは@Martin Velezに回答するための上記の@ Emmanuelの回答の拡張です。 (また、私はまだコメントを書くことができないので、これが適切な場所ではない場合は、申し訳ありません!)

どのバージョンのAngular OPが使用していたのかわかりませんが、Angular#1.2 +では少なくとも公式ドキュメントで https://docs.angularjs.org/api/ ng/type/ngModel.NgModelController#$ render 、$ renderは次のようにリストされます。

ビューを更新する必要があるときに呼び出されます。 ng-modelディレクティブのユーザーがこのメソッドを実装することが期待されています。

$ render()メソッドは、次の状況で呼び出されます。

$ rollbackViewValue()が呼び出されます。ビュー値を最後にコミットされた値にロールバックする場合、入力コントロールを更新するために$ render()が呼び出されます。 ng-modelによって参照される値はプログラムで変更され、$ modelValueと$ viewValueの両方が前回と異なります。 ng-modelは詳細な監視を行わないため、$ render()は、$ modelValueと$ viewValueの値が実際に以前の値と異なる場合にのみ呼び出されます。

これは、ディレクティブからngModelを$ watchする正しい方法は、ngModelを要求し、ngModelControllerを注入するリンク関数を実装することであると解釈します。次に、$ render-on-change($ watch)などに組み込まれているngModel APIを使用します。

4
RoboBear

それを行うには2つの方法があります。

1)$attrs.[any_attribute]を使用して、任意のリスナーを設定できます

2)2つの方法binding変数でスコープを分離し、それにリスナーを設定できます。さらに必要な場合は、こちらの記事を参照してください。

http://www.w3docs.com/snippets/angularjs/bind-variable-inside-angularjs-directive-isolated-scope.html

1