wake-up-neo.com

Beobachten Sie den Controller-Modellwert aus der Direktive

Ich versuche, den $viewValue eines Controllers aus einer Direktive heraus zu beobachten.

geige: 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);
            });
        }
    } 
});

Die $ watch-Funktion erkennt den Modellwechsel nach 2 Sekunden vom Controller nicht. Was vermisse ich?

22
Dustin

$watch akzeptiert den "Namen" der Eigenschaft, die im Gültigkeitsbereich überwacht werden soll. Sie werden aufgefordert, den Wert zu überwachen. Ändern Sie ihn, um attrs.ngModel zu sehen, der "bar" zurückgibt, jetzt sehen Sie scope.bar. Sie können den Wert auf dieselbe Weise abrufen, wie Sie waren, oder scope[attrs.ngModel] verwenden. Dies ist, als würde scope["bar"] sagen, der wiederum scope.bar entspricht.

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

Um den Kommentar des Benutzers 271996 zu verdeutlichen: scope.$eval wird verwendet, weil Sie die Objektnotation an das ng-model-Attribut übergeben können. Das heißt ng-model="someObj.someProperty", das nicht funktioniert, weil scope["someObj.someProperty"] nicht gültig ist. scope.$eval wird verwendet, um diese Zeichenfolge in einem tatsächlichen Objekt auszuwerten, sodass scope["someObj.someProperty"]scope.someObj.someProperty wird.

48
Jonathan Rowny

Wollte hinzufügen: in 1.2.x, mit isoliertem Umfang, funktionieren die obigen nicht. http://jsfiddle.net/TfTr5/23/

Eine Problemumgehung, die ich mir ausgedacht hatte, war die Tatsache, dass $ watch auch eine Funktion akzeptiert, sodass Sie auf Ihren Controller zugreifen können.

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

Geige arbeiten: http://jsfiddle.net/TfTr5/24/

Wenn jemand eine Alternative hat, würde ich mich sehr freuen!

9
wlingke

Wenn Sie einen Wert innerhalb eines isolierten Bereichs binden möchten, gibt es zwei Möglichkeiten, dies zu tun. Die erste Möglichkeit, die Sie verwenden können, ist, auch wenn Sie keinen isolierten Bereich haben.

1) benutze $attrs.any_attribute und binde es (set in watch)

2) Verwenden Sie die Methode 2 ways binding ('=') und legen Sie sie im Listener fest

wenn Sie mehr mit Beispielen wollen, ist hier ein großartiger Artikel 

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

1

Wenn Sie einen Modellwert entprellen möchten, sollten Sie die Debounce-Einstellung in ng-model-option erwähnen:

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

Zum Beispiel: Diese Uhr wird 1000 ms nach Änderung ausgelöst und bei neuen Änderungen zurückgesetzt.

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

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

0
Frankey