W AngularJS można było określić obserwatorów, którzy będą obserwować zmiany zmiennych zakresu za pomocą $watch
funkcji $scope
. Jaki jest odpowiednik obserwowania zmian zmiennych (na przykład zmiennych składowych) w Angular?
213
W AngularJS można było określić obserwatorów, którzy będą obserwować zmiany zmiennych zakresu za pomocą $watch
funkcji $scope
. Jaki jest odpowiednik obserwowania zmian zmiennych (na przykład zmiennych składowych) w Angular?
Odpowiedzi:
W Angular 2 wykrywanie zmian odbywa się automatycznie ...
$scope.$watch()
i$scope.$digest()
RIPNiestety sekcja Wykrywanie zmian w przewodniku dla deweloperów nie została jeszcze napisana (w dolnej części strony Przegląd architektury znajduje się symbol zastępczy , w sekcji „Inne rzeczy”).
Oto moje rozumienie działania detekcji zmian:
setTimeout()
wewnątrz naszych komponentów zamiast czegoś takiego jak$timeout
... ponieważsetTimeout()
jest załatany małpą.ChangeDetectorRef
.) Te detektory zmian są tworzone, gdy Angular tworzy komponenty. Śledzą stan wszystkich twoich powiązań, w celu brudnego sprawdzania. W pewnym sensie są one podobne do automatycznych$watches()
ustawień Angulara 1 dla{{}}
powiązań szablonów.W przeciwieństwie do Angulara 1, wykres wykrywania zmian jest ukierunkowanym drzewem i nie może mieć cykli (to sprawia, że Angular 2 jest o wiele bardziej wydajny, jak zobaczymy poniżej).
onPush
strategii wykrywania zmian na żadnym ze swoich komponentów), każdy element w drzewie jest sprawdzany raz (TTL = 1) ... od góry, w kolejności od głębokości do pierwszej. (Cóż, jeśli jesteś w trybie deweloperskim, wykrywanie zmian działa dwa razy (TTL = 2). Więcej informacji na ten temat znajdziesz w ApplicationRef.tick () .) Wykonuje sprawdzanie wszystkich powiązań przy użyciu tych obiektów wykrywacza zmian.Jeśli dane komponentu, które chcesz oglądać, są podstawową właściwością wejściową (ciąg, wartość logiczna, liczba), możesz zaimplementować,
ngOnChanges()
aby otrzymywać powiadomienia o zmianach.Jeżeli nieruchomość jest rodzajem wejścia odniesienia (obiekt, tablica itd.), Ale odwołanie nie uległ zmianie (np dodano element do istniejącej tablicy), trzeba wdrożyć
ngDoCheck()
(patrz to tak odpowiedź na dłużej na to).Powinieneś zmienić tylko właściwości komponentu i / lub właściwości komponentów potomnych (ze względu na implementację pojedynczego przejścia drzewa - tj. Jednokierunkowy przepływ danych). Oto plunker, który to narusza. Potężne rury mogą cię tutaj potknąć .
Inne odniesienia, aby dowiedzieć się więcej:
onPush
.źródło
host
dokumentacją „Host nasłuchiwania” w dokumentacji interfejsu API dyrektywy Metadata . Wyjaśnia, jak słuchać globalnych wydarzeń z wewnątrz strefy kątowej (więc wykrywanie zmian będzie uruchamiane zgodnie z potrzebami). Ta odpowiedź ma działającego plunkera.To zachowanie jest teraz częścią cyklu życia komponentu.
Komponent może zaimplementować metodę ngOnChanges w interfejsie OnChanges , aby uzyskać dostęp do zmian danych wejściowych.
Przykład:
źródło
Jeśli oprócz automatycznego wiązania dwukierunkowego chcesz wywołać funkcję, gdy zmienia się wartość, możesz przerwać składnię skrótu wiązania dwustronnego do wersji bardziej szczegółowej.
<input [(ngModel)]="yourVar"></input>
jest skrótem od
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(patrz np. http://victorsavkin.com/post/119943127151/angular-2-template-syntax )
Możesz zrobić coś takiego:
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
źródło
Możesz używać
getter function
lubget accessor
działać jako zegarek na kanciastym 2.Zobacz demo tutaj .
źródło
Oto inne podejście wykorzystujące funkcje gettera i settera dla modelu.
źródło
(change)
programów obsługi do każdego z nich; Nie chcę dodawaćget|sets
s do każdej właściwości w moim modelu; to nie pomoże, aby dodaćget|set
dothis.object
;ngOnChanges()
wykrywa tylko zmiany w@Input
s . Święta manna! Co oni nam zrobili ??? Oddaj nam jakiś rodzaj głębokiej obserwacji!Jeśli chcesz uczynić to wiązaniem dwukierunkowym, możesz użyć
[(yourVar)]
, ale musisz zaimplementowaćyourVarChange
zdarzenie i wywołać je za każdym razem, gdy zmieniasz zmienną.Coś takiego do śledzenia zmiany bohatera
a potem, gdy twój bohater się zmieni, zadzwoń
this.heroChange.emit(this.hero);
[(hero)]
wiążące zrobi resztę za Ciebiepatrz przykład tutaj:
http://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview
źródło
Spróbuj tego, gdy aplikacja nadal żąda
$parse
,$eval
,$watch
jak zachowanie w kątowymhttps://github.com/vinayk406/angular-expression-parser
źródło
To nie odpowiada bezpośrednio na pytanie, ale przy różnych okazjach padałem na to pytanie dotyczące przepełnienia stosu, aby rozwiązać coś, czego użyłbym $ watch w angularJs. Skończyło się na innym podejściu niż opisano w bieżących odpowiedziach i chcę się nim podzielić, na wypadek, gdyby ktoś uznał to za przydatne.
Techniką, której używam, aby osiągnąć coś podobnego,
$watch
jest użycieBehaviorSubject
( więcej na ten temat tutaj ) w usłudze Angular i pozwolenie moim komponentom na subskrypcję, aby uzyskać (obserwować) zmiany. Jest to podobne do$watch
w angularJs, ale wymaga nieco więcej konfiguracji i zrozumienia.W moim komponencie:
W mojej służbie
Oto demo na Stackblitz
źródło