Wie abonniere ich eine Eigenschaftsänderung, wenn ich die controller as
Syntax verwende?
controller('TestCtrl', function ($scope) {
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
// not working
$scope.$watch("name",function(value){
console.log(value)
});
});
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
Antworten:
Binden Sie einfach den relevanten Kontext.
Beispiel: http://jsbin.com/yinadoce/1/edit
AKTUALISIEREN:
Bogdan Gersaks Antwort ist eigentlich eine Art Äquivalent, beide Antworten versuchen, sich
this
mit dem richtigen Kontext zu verbinden. Ich fand seine Antwort jedoch sauberer.Vor diesem Hintergrund muss man in erster Linie die zugrunde liegende Idee verstehen .
UPDATE 2:
Für diejenigen, die ES6 verwenden, erhalten Sie durch die Verwendung
arrow function
eine Funktion mit dem richtigen Kontext OOTB.Beispiel
quelle
$scope
Für Sie ist eine Art Service, der diese Art von Methoden liefert.name
inreturn this.name;
auf den Namen des Controllers oder die Eigenschaft "name
" bezieht ?angular.bind
gibt eine Funktion mit einem begrenzten Kontext zurück (Argument 1). In unserem Fall binden wirthis
, die Instanz des Controllers, an die Funktion (arg # 2),this.name
dh die Eigenschaftname
der Instanz des Controllers.Normalerweise mache ich das:
quelle
$scope.$watch
und diese Funktion zu verwenden, um einen Wert aus dem Abschluss zurückzugeben. Ich habe noch kein anderes Beispiel dafür gefunden, aber es funktioniert und ist das Beste. Der Grund, warum ich die unten stehende Antwort nicht gewählt habe (dh$scope.$watch('test.name', function (value) {});
), ist, dass ich das, was ich meinen Controller nannte, in meiner Vorlage oder im $ stateProvider von ui.router fest codieren muss und jede Änderung dort den Beobachter versehentlich beschädigen würde.angular.bind
) besteht darin, ob Sie an den Abschluss bindenthis
oder einfach einen anderen Verweis hinzufügen möchtenthis
. Diese sind funktional gleichwertig, und meiner Erfahrung nach ist diese Art der Wahl oft ein subjektiver Aufruf und eine sehr starke Meinung.$scope.$watch( ()=> { return this.name' }, function(){} )
Fetter Pfeil zur Rettung() => this.name
$scope.$watchCollection
zumoldVal, newVal
Laufen bringen und trotzdem die Parameter bekommen?Sie können verwenden:
Dies funktioniert JSFiddle mit Ihrem Beispiel.
quelle
Ähnlich wie bei der Verwendung des "Tests" von "TestCtrl als Test", wie in einer anderen Antwort beschrieben, können Sie Ihrem Bereich "Selbst" zuweisen:
Auf diese Weise sind Sie nicht an den im DOM angegebenen Namen gebunden ("TestCtrl as test") und vermeiden auch die Notwendigkeit, (dies) an eine Funktion zu binden.
... zur Verwendung mit dem angegebenen Original-HTML:
quelle
$scope
einen Dienst. Wenn wir also hinzufügen$scope.self = this
, dann in einem anderen Controller, wenn wir dasselbe tun: Was passiert dort?AngularJs 1.5 unterstützt die Standard $ ctrl für die ControllerAs-Struktur.
quelle
Sie können tatsächlich eine Funktion als erstes Argument einer $ watch () übergeben:
Das heißt, wir können unsere this.name-Referenz zurückgeben:
Lesen Sie einen interessanten Beitrag zum Thema controllerAs https://toddmotto.com/digging-into-angulars-controller-as-syntax/
quelle
Sie können den Winkelkomponenten-Lebenszyklus von $ onChanges verwenden .
Siehe Dokumentation hier: https://docs.angularjs.org/guide/component im Abschnitt Komponentenbasierte Anwendung
quelle
Das Schreiben einer $ watch in ES6-Syntax war nicht so einfach wie ich erwartet hatte. Folgendes können Sie tun:
quelle
HINWEIS : Dies funktioniert nicht, wenn View und Controller in einer Route oder über ein Direktivendefinitionsobjekt gekoppelt sind. Was unten gezeigt wird, funktioniert nur, wenn der HTML-Code einen "SomeController as SomeCtrl" enthält. Genau wie Mark V. im Kommentar unten betont, und genau wie er sagt, ist es besser, so zu tun, wie Bogdan es tut.
Ich benutze:
var vm = this;
am Anfang des Controllers, um das Wort "dies" aus dem Weg zu räumen. Dannvm.name = 'Max';
und in der Uhr ichreturn vm.name
. Ich benutze das "vm" genau wie @Bogdan "self" benutzt. Diese Variable, sei es "vm" oder "self", wird benötigt, da das Wort "this" innerhalb der Funktion einen anderen Kontext annimmt. (Die Rückgabe dieses Namens würde also nicht funktionieren.) Und ja, Sie müssen $ scope in Ihre schöne "Controller as" -Lösung einfügen, um $ watch zu erreichen. Siehe John Papas Style Guide: https://github.com/johnpapa/angularjs-styleguide#controllersquelle
Hier erfahren Sie, wie Sie dies ohne $ scope (und $ watch!) Tun. Top 5 Fehler - Missbrauch der Uhr
Wenn Sie die Syntax "controller as" verwenden, ist es besser und sauberer, die Verwendung von $ scope zu vermeiden.
Hier ist mein Code in JSFiddle . (Ich verwende einen Dienst, um den Namen zu speichern, andernfalls verursachen die Set- und Get-Methoden von ES5 Object.defineProperty unendliche Aufrufe.
quelle