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?
Das Problem ist, dass Sie $watch
ing 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/
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.
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)
};
}
};
});
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
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.
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