Jak zasubskrybować zmianę właściwości przy użyciu controller as
składni?
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>
Odpowiedzi:
Po prostu połącz odpowiedni kontekst.
Przykład: http://jsbin.com/yinadoce/1/edit
AKTUALIZACJA:
Odpowiedź Bogdana Gersaka jest właściwie odpowiednikiem, obie odpowiedzi starają się połączyć z odpowiednim
this
kontekstem. Jednak jego odpowiedź była dla mnie czystsza.Mając to na uwadze, przede wszystkim musisz zrozumieć leżącą u podstaw ideę .
AKTUALIZACJA 2:
Dla tych, którzy używają ES6, używając
arrow function
dostaniesz funkcję z odpowiednim kontekstem OOTB.Przykład
źródło
$scope
dla ciebie jest to rodzaj usługi, która dostarcza tego rodzaju metody.name
wreturn this.name;
odnosi się tutaj do nazwy administratora lub właściwości „name
”?angular.bind
zwraca funkcję z ograniczonym kontekstem (arg # 1). W naszym przypadku łączymy sięthis
, który jest instancją kontrolera, z funkcją (arg # 2), a więcthis.name
oznacza własnośćname
instancji kontrolera.Zwykle robię to:
źródło
$scope.$watch
i użyciem tej funkcji do zwrócenia wartości z zamknięcia. Nie spotkałem jeszcze innego przykładu, ale działa i jest najlepszy. Powodem, dla którego nie wybrałem odpowiedzi poniżej (tj.$scope.$watch('test.name', function (value) {});
), Jest to, że wymagało to trwałego zakodowania tego, co nazwałem mój kontroler w moim szablonie lub w $ stateProvider ui.router, a każda zmiana spowodowałaby nieumyślne uszkodzenie obserwatora.angular.bind
) jest to, czy chcesz się powiązać,this
czy po prostu dodać kolejne odniesienie dothis
zamknięcia. Są one funkcjonalnie równoważne iz mojego doświadczenia wynika, że tego rodzaju wybór jest często subiektywnym wezwaniem i sprawą bardzo mocnej opinii.$scope.$watch( ()=> { return this.name' }, function(){} )
Gruba strzała na ratunek() => this.name
$scope.$watchCollection
i nadal mieć parametryoldVal, newVal
?Możesz użyć:
To działa JSFiddle z twoim przykładem.
źródło
Podobnie jak przy użyciu opcji „test” z „TestCtrl jako test”, jak opisano w innej odpowiedzi, możesz przypisać zakres „samodzielnie”:
W ten sposób nie jesteś przywiązany do nazwy określonej w DOM („TestCtrl jako test”), a także unikasz konieczności wiązania .bind (this) z funkcją.
... do użytku z określonym oryginalnym kodem HTML:
źródło
$scope
jest to usługa, więc jeśli dodamy$scope.self = this
, to w innym kontrolerze, jeśli zrobimy to samo, co się tam stanie?AngularJs 1.5 obsługuje domyślną $ ctrl dla struktury ControllerAs.
źródło
faktycznie możesz przekazać funkcję jako pierwszy argument $ watch ():
Co oznacza, że możemy zwrócić odwołanie this.name:
Przeczytaj interesujący post o kontrolerze W temacie https://toddmotto.com/digging-into-angulars-controller-as-syntax/
źródło
Możesz użyć cyklu życia komponentu kątowego $ onChanges .
zobacz dokumentację tutaj: https://docs.angularjs.org/guide/component w sekcji Aplikacje oparte na komponentach
źródło
Napisanie zegarka $ watch w składni ES6 nie było tak łatwe, jak się spodziewałem. Oto, co możesz zrobić:
źródło
UWAGA : To nie działa, gdy widok i kontroler są połączone w trasie lub za pośrednictwem obiektu definicji dyrektywy. To, co pokazano poniżej, działa tylko wtedy, gdy w kodzie HTML znajduje się „SomeController as SomeCtrl”. Tak jak zaznacza Mark V. w komentarzu poniżej, i tak jak mówi, lepiej robić tak, jak robi to Bogdan.
Używam:
var vm = this;
na początku kontrolera, aby słowo „to” zniknęło mi z drogi. Wtedyvm.name = 'Max';
i na zegarku jareturn vm.name
. Używam „vm” tak samo, jak @Bogdan używa „self”. Ta zmienna, czy to „vm”, czy „self”, jest potrzebna, ponieważ słowo „this” przyjmuje inny kontekst wewnątrz funkcji. (więc zwrócenie this.name nie zadziałałoby) I tak, musisz wstrzyknąć $ scope do swojego pięknego rozwiązania „controller as”, aby dotrzeć do $ watch. Zobacz przewodnik po stylu Johna Papy: https://github.com/johnpapa/angularjs-styleguide#controllersźródło
Oto jak to zrobić bez $ scope (i $ watch!) Top 5 błędów - nadużywanie zegarka
Jeśli używasz składni „kontroler jako”, lepiej i czyściej unikać używania $ scope.
Oto mój kod w JSFiddle . (Używam usługi do przechowywania nazwy, w przeciwnym razie metody set i get ES5 Object.defineProperty powodują nieskończone wywołania.
źródło