wake-up-neo.com

$ watch ngModel von innerhalb der Direktive unter Verwendung des Isolate-Bereichs

Ich versuche, meinen Modellwert aus meiner Verknüpfungsfunktion heraus zu beobachten.

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

Wenn ich den Modellwert in meinem Controller ändere, wird die $ watch-Funktion nicht ausgelöst.

$scope.myModel = "ACT";

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

Fiddle: http://jsfiddle.net/dkrotts/BtrZH/4/

Was vermisse ich hier?

54
Dustin

Das Problem ist, dass Sie $watching attrs.ngModel was gleich "myModel" ist. Sie haben "myModel" nicht in Ihrem Gültigkeitsbereich gebunden. Du möchtest $watch "Modell". Das ist es, was im Geltungsbereich Ihrer Richtlinie festgelegt ist. Siehe http://jsfiddle.net/BtrZH/5/

31
dnc253

Sie müssen eine Funktion beobachten, die den von Ihnen beobachteten $ modelValue zurückgibt.

Der folgende Code zeigt ein einfaches Beispiel:

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

Hier ist ein Plunker der gleichen Idee in Aktion.

149
Ben Lesh

Der richtige Weg, dies zu tun, ist:

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

Hier ist eine andere Möglichkeit, dies zu tun:

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

Auf diese Weise können Sie Wertänderungen mit solchen Binds abhören

8
user2978730

Dies ist eine Erweiterung von @ Emmanuels Antwort auf @ Martin Velez, obwohl ich weiß, dass es ziemlich spät ist! (Außerdem kann ich noch keine Kommentare abgeben. Wenn dies nicht der richtige Ort dafür ist, tut mir leid!)

Ich bin nicht sicher, welche Version von Angular OP verwendet wurde, aber in Angular # 1.2 + zumindest in den offiziellen Dokumenten https://docs.angularjs.org/api/ ng/type/ngModel.NgModelController # $ render , $ render wird folgendermaßen aufgelistet:

Wird aufgerufen, wenn die Ansicht aktualisiert werden muss. Es wird erwartet, dass der Benutzer der ng-model-Direktive diese Methode implementiert.

Die Methode $ render () wird in den folgenden Situationen aufgerufen:

$ rollbackViewValue () wird aufgerufen. Wenn der Ansichtswert auf den letzten festgeschriebenen Wert zurückgesetzt wird, wird $ render () aufgerufen, um das Eingabesteuerelement zu aktualisieren. Der Wert, auf den ng-model verweist, wird programmgesteuert geändert, und sowohl $ modelValue als auch $ viewValue unterscheiden sich vom letzten Mal. Da ng-model keine Deep Watch ausführt, wird $ render () nur aufgerufen, wenn sich die Werte von $ modelValue und $ viewValue tatsächlich von ihrem vorherigen Wert unterscheiden.

Ich interpretiere dies so, dass der richtige Weg, ein ngModel von einer Direktive aus zu beobachten, darin besteht, ngModel zu erfordern und eine Link-Funktion zu implementieren, die ngModelController einfügt. Verwenden Sie dann die in $ render-on-change ($ watch) integrierte ngModel-API oder was auch immer.

4
RoboBear

Es gibt zwei Möglichkeiten, dies zu tun.

1) Sie können $attrs.[any_attribute] und setzen Sie darauf einen beliebigen Hörer

2) Sie können den Gültigkeitsbereich mit einer 2-Wege-Bindungsvariablen isolieren und einen Listener darauf setzen. Wenn Sie mehr wollen, finden Sie hier einen coolen Artikel

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

1