22

$viewValueディレクティブ内からコントローラーの角度を監視しようとしています。

フィドル: http://jsfiddle.net/dkrotts/TfTr5/5/

function foo($scope, $timeout) {
    $scope.bar = "Lorem ipsum";

    $timeout(function() {
        $scope.bar = "Dolor sit amet";
    }, 2000);
}

myApp.directive('myDirective', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, controller) {
            scope.$watch(controller.$viewValue, function() {
                console.log("Changed to " + controller.$viewValue);
            });
        }
    } 
});

そのままでは、$watch 関数は、コントローラー内から 2 秒後に行われたモデル変更をキャッチしていません。私は何が欠けていますか?

4

4 に答える 4

48

$watchスコープで監視するプロパティの「名前」を受け入れ、値を監視するように要求しています。attrs.ngModel「バー」を返すウォッチに変更すると、ウォッチしていることになりますscope.bar。値は、以前と同じように取得することも、同じように使用することもscope[attrs.ngModel]できscope["bar"]ますscope.bar

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

user271996のコメントを明確にするために:scope.$evalオブジェクト表記をng-model属性に渡すことができるために使用されます。つまり、が無効ng-model="someObj.someProperty"であるためscope["someObj.someProperty"]に機能しません。scope.$evalは、その文字列を実際のオブジェクトに評価して、にscope["someObj.someProperty"]なるようにするために使用されますscope.someObj.someProperty

于 2013-01-28T17:57:23.520 に答える
9

追加したい: 1.2.x では、スコープが分離されているため、上記は機能しません。http://jsfiddle.net/TfTr5/23/

私が思いついた回避策は、 $watch も関数を受け入れるという事実を使用することでした。これにより、それを使用してコントローラーにアクセスできます。

scope.$watch(
    function(){return controller.$viewValue},
    function(newVal, oldVal){
        //code
    }
)

作業フィドル: http://jsfiddle.net/TfTr5/24/

誰かが代わりを持っているなら、私は喜んでそれを歓迎します!

于 2013-12-06T19:33:18.543 に答える
-1

モデル値でデバウンスが必要な場合は、ng-model-optionのデバウンス設定に言及する価値があります:

<input type="text" ng-model-options="{ debounce: 1000 }" ng-model="search"/>

例: この時計は変更後 1000 ミリ秒でトリガーされ、新しい変更でリセットされます。

scope.$watch(attrs.ngModel, function(newValue) { });

https://docs.angularjs.org/api/ng/directive/ngModelOptions

于 2015-06-13T20:16:01.010 に答える