Musisz wiedzieć, jak działa AngularJS, aby to zrozumieć.
Cykl trawienia i zakres $
Przede wszystkim AngularJS definiuje koncepcję tak zwanego cyklu trawienia . Cykl ten można uznać za pętlę, podczas której AngularJS sprawdza, czy są jakieś zmiany we wszystkich zmiennych obserwowanych przez wszystkie $scope
s. Jeśli więc $scope.myVar
zdefiniowałeś w kontrolerze i ta zmienna została oznaczona do oglądania , to domyślnie mówisz AngularJS, aby monitorował zmiany myVar
w każdej iteracji pętli.
Naturalnym następczym pytaniem byłoby: czy wszystko jest związane z $scope
oglądaniem? Na szczęście nie. Jeśli będziesz obserwować zmiany w każdym obiekcie w swoim $scope
wnętrzu, to szybko zajmie to całe wieki, aby ocenić i szybko wpadniesz na problemy z wydajnością. Dlatego zespół AngularJS dał nam dwa sposoby zadeklarowania $scope
zmiennej jako obserwowanej (czytaj poniżej).
$ watch pomaga nasłuchiwać zmian zakresu $
Istnieją dwa sposoby zadeklarowania $scope
zmiennej jako obserwowanej.
- Używając go w szablonie za pomocą wyrażenia
<span>{{myVar}}</span>
- Dodając go ręcznie za pośrednictwem
$watch
usługi
Ad 1) Jest to najczęstszy scenariusz i jestem pewien, że widziałeś go wcześniej, ale nie wiedziałeś, że stworzył zegarek w tle. Tak było! Korzystanie z dyrektyw AngularJS (np. ng-repeat
) Może również tworzyć niejawne zegarki.
Ad 2) W ten sposób tworzysz własne zegarki . $watch
Usługa pomaga uruchomić kod, gdy $scope
zmieni się pewna wartość dołączona do pliku. Jest rzadko używany, ale czasem jest pomocny. Na przykład, jeśli chcesz uruchomić jakiś kod za każdym razem, gdy zmienia się „myVar”, możesz wykonać następujące czynności:
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
$ Apply umożliwia zintegrowanie zmian z cyklem podsumowania
Możesz myśleć o tej $apply
funkcji jak o mechanizmie integracji . Widzisz, za każdym razem, gdy zmieniasz obserwowaną zmienną dołączoną$scope
bezpośrednio do obiektu, AngularJS będzie wiedział, że zmiana nastąpiła. Jest tak, ponieważ AngularJS już wiedział, że monitoruje te zmiany. Jeśli więc zdarzy się to w kodzie zarządzanym przez platformę, cykl podsumowania będzie kontynuowany.
Czasami jednak chcesz zmienić jakąś wartość poza światem AngularJS i zobaczyć, jak zmiany propagują się normalnie. Zastanów się - masz $scope.myVar
wartość, która zostanie zmodyfikowana w module $.ajax()
obsługi jQuery . Stanie się to w pewnym momencie w przyszłości. AngularJS nie może się doczekać, aby tak się stało, ponieważ nie polecono mu czekać na jQuery.
Aby rozwiązać ten problem, $apply
został wprowadzony. Umożliwia jawne rozpoczęcie cyklu trawienia. Powinieneś jednak użyć tego tylko do migracji niektórych danych do AngularJS (integracja z innymi frameworkami), ale nigdy nie używaj tej metody w połączeniu ze zwykłym kodem AngularJS, ponieważ AngularJS zgłosi błąd.
Jak to wszystko ma się do DOM?
Cóż, powinieneś naprawdę postępować zgodnie z samouczkiem, skoro wiesz już wszystko. Cykl podsumowania upewni się, że interfejs użytkownika i kod JavaScript pozostaną zsynchronizowane, oceniając każdego obserwatora podłączonego do wszystkich, $scope
o ile nic się nie zmieni. Jeśli w pętli podsumowania nie nastąpią już żadne zmiany, uznaje się to za zakończone.
Możesz dołączyć obiekty do $scope
obiektu albo jawnie w kontrolerze, albo zadeklarując je w {{expression}}
formie bezpośrednio w widoku.
Mam nadzieję, że pomoże to wyjaśnić podstawową wiedzę na ten temat.
Dalsze odczyty:
W AngularJS aktualizujemy nasze modele, a nasze widoki / szablony aktualizują DOM „automatycznie” (poprzez wbudowane lub niestandardowe dyrektywy).
$ Apply i $ watch, obie metody Scope, nie są powiązane z DOM.
Strona Pojęcia (sekcja „ Środowisko wykonawcze”) zawiera całkiem dobre objaśnienie pętli $ digest, $ Apply, kolejki $ evalAsync i listy obserwowanych $. Oto zdjęcie towarzyszące tekstowi:
Jakikolwiek kod ma dostęp do zakresu - zwykle kontrolery i dyrektywy (ich funkcje łącza i / lub ich kontrolery) - mogą ustawić „ watchExpression ”, które AngularJS oceni na podstawie tego zakresu. Ta ocena ma miejsce za każdym razem, gdy AngularJS wejdzie do swojej pętli $ streszczenia (w szczególności pętli „$ watch list”). Możesz oglądać indywidualne właściwości zakresu, możesz zdefiniować funkcję, aby oglądać dwie właściwości razem, możesz obserwować długość tablicy itp.
Kiedy coś się dzieje „wewnątrz AngularJS” - np. Wpisujesz w polu tekstowym, które ma włączone dwukierunkowe wiązanie danych AngularJS (tj. Używa modelu ng), następuje wywołanie zwrotne $ http itp. - $ Apply zostało już wywołane, więc znajdują się w prostokącie „AngularJS” na powyższym rysunku. Wszystkie wyrażenia watch będą oceniane (być może więcej niż jeden raz - dopóki nie zostaną wykryte dalsze zmiany).
Kiedy coś się dzieje „poza AngularJS” - np. Użyłeś bind () w dyrektywie, a następnie to zdarzenie zostaje wywołane, co powoduje wywołanie twojego wywołania zwrotnego lub niektóre wywołania wywołania zwrotnego zarejestrowane przez jQuery - wciąż jesteśmy w „rodzimym” prostokącie. Jeśli kod zwrotny modyfikuje cokolwiek, co ogląda dowolny zegarek $, wywołanie $ stosuje się, aby dostać się do prostokąta AngularJS, powodując uruchomienie pętli $ digest, a zatem AngularJS zauważy zmianę i wykona swoją magię.
źródło
scope.$apply(scope.model)
, nie rozumiem, jakie dane są przesyłane i jak są przenoszone we właściwe miejsce w modelu?scope.$apply(scope.model)
będzie po prostu oceniaćscope.model
jako wyrażenie kątowe, a następnie wejdzie w pętlę $ digest. W artykule, do którego się odwołujesz, prawdopodobniescope.$apply()
byłby wystarczający, ponieważ model jest już oglądany. Funkcja stop () aktualizuje model (uważam, że toUpdate jest odniesieniem do scope.model), a następnie wywoływane jest $ Apply.$watch
uruchomieniowego ” lub na stronie, a drugi link jest uszkodzony - jak na razie). Boleśnie wersje archiwalne nie buforowały żadnego procesu asynchronicznego tworzącego treść.AngularJS rozszerza tę pętlę zdarzeń , tworząc coś o nazwie
AngularJS context
.$ watch ()
Za każdym razem, gdy wiążą się coś w interfejsie włożysz
$watch
w$watch
liście .Tutaj mamy
$scope.user
, który jest związany z pierwszym wejściem, i mamy$scope.pass
, który jest powiązany z drugim wejściem . W ten sposób dodajemy dwie listy$watch
do$watch
listy .Kiedy nasz szablon zostanie załadowany, AKA w fazie łączenia, kompilator wyszuka każdą dyrektywę i utworzy wszystkie
$watch
potrzebne.Angularjs zapewnia
$watch
,$watchcollection
i$watch(true)
. Poniżej znajduje się zgrabny schemat wyjaśniający wszystkie trzy wzięte głęboko od obserwatorów .http://jsfiddle.net/2Lyn0Lkb/
$digest
pętlaGdy przeglądarka odbierze zdarzenie, którym można zarządzać w kontekście AngularJS,
$digest
pętla zostanie uruchomiona . Ta pętla składa się z dwóch mniejszych pętli. Jeden przetwarza$evalAsync
kolejkę, a drugi przetwarza$watch list
.$digest
Pętla poprzez liście$watch
, że mamyTutaj mamy tylko jeden,
$watch
ponieważ ng-click nie tworzy żadnych zegarków.Naciskamy przycisk.
$digest
Pętla zostanie uruchomiony i poprosi każde $ obserwować zmiany.$watch
który obserwował zmiany w $ scope.name zgłasza zmianę, wymusi kolejną$digest
pętlę.$digest
pętlę. Oznacza to, że za każdym razem, gdy piszemy literę w danych wejściowych, pętla będzie sprawdzać każde$watch
na tej stronie.Zastosuj $ ()
Jeśli zadzwonisz,
$apply
gdy zostanie wywołane zdarzenie, przejdzie ono przez kontekst kątowy, ale jeśli go nie wywołasz, będzie działać poza nim. To takie proste.$apply
wywoła$digest()
pętlę wewnętrznie i wykona iterację po wszystkich zegarkach, aby upewnić się, że DOM został zaktualizowany o nowo zaktualizowaną wartość.$apply()
Metoda spowoduje obserwatorów na całym$scope
łańcuchu natomiast$digest()
metoda spowoduje jedynie obserwatorów na prąd$scope
i jejchildren
. Gdy żaden z wyżej wymienionych$scope
obiektów nie musi wiedzieć o lokalnych zmianach, możesz użyć$digest()
.źródło
I okazało się bardzo filmów pogłębione który pokrywa
$watch
,$apply
,$digest
i strawienia w cyklach:AngularJS - Zrozumienie Watcher, $ watch, $ watchGroup, $ watchCollection, ng-change
AngularJS - Zrozumienie cyklu trawienia (faza trawienia lub proces trawienia lub pętla trawienia)
Samouczek AngularJS - Zrozumienie $ Apply i $ digest (dogłębnie)
Poniżej znajduje się kilka slajdów używanych w tych filmach w celu wyjaśnienia pojęć (na wszelki wypadek, jeśli powyższe linki zostaną usunięte / nie działają).
Na powyższym obrazie „$ scope.c” nie jest obserwowany, ponieważ nie jest używany w żadnym powiązaniu danych (w znacznikach). Pozostałe dwa (
$scope.a
i$scope.b
) będą oglądane.Z powyższego obrazu: W oparciu o odpowiednie zdarzenie przeglądarki, AngularJS przechwytuje zdarzenie, wykonuje cykl podsumowania (przechodzi wszystkie zegarki w celu wprowadzenia zmian), wykonuje funkcje zegarka i aktualizuje DOM. Jeśli nie są to zdarzenia przeglądarki, cykl podsumowania można uruchomić ręcznie za pomocą
$apply
lub$digest
.Więcej o
$apply
i$digest
:źródło
Są
$watchGroup
i$watchCollection
również. W szczególności,$watchGroup
jest bardzo pomocne, jeśli chcemy wywołać funkcję zaktualizować obiekt, który ma wiele właściwości w widoku, który nie jest Dom przedmiot, na przykład inny pogląd na płótnie, WebGL czy żądanie serwera.Tutaj link do dokumentacji .
źródło
$watchCollection
ale widzę, że już to zrobiłeś. Oto dokumentacja na ten temat ze strony AngularJS. Zapewniają bardzo ładny obraz$watch
głębi. Uwaga: informacje znajdują się w dolnej części strony.Po prostu przestań czytać WSZYSTKIE powyższe, nudne i senne (przepraszam, ale to prawda). Bardzo techniczny, dogłębny, szczegółowy i suchy. Dlaczego piszę Ponieważ AngularJS jest ogromny, wiele wzajemnie połączonych koncepcji może doprowadzić do szału każdego. Często zadawałem sobie pytanie, czy nie jestem wystarczająco inteligentny, aby je zrozumieć? Nie! To dlatego, że tak niewielu potrafi wytłumaczyć technologię w języku for-dummie bez wszystkich terminologii! OK, pozwól mi spróbować:
1) Wszystkie są rzeczami napędzanymi zdarzeniami. (Słyszę śmiech, ale czytam dalej)
Jeśli nie wiesz, co to jest zdarzenie sterowane, a następnie pomyśl, że umieścisz przycisk na stronie, podłącz go z funkcją za pomocą „kliknięcia”, czekając, aż użytkownicy klikną go, aby wywołać działania, które umieścisz w funkcjonować. Albo pomyśl o „wyzwalaczu” SQL Server / Oracle.
2) $ watch to „po kliknięciu”.
Na szczególną uwagę zasługuje to, że jako parametry przyjmuje się 2 funkcje, pierwsza podaje wartość ze zdarzenia, druga bierze pod uwagę wartość ...
3) $ digest to szef, który niestrudzenie się rozgląda , bla-bla-bla, ale dobry szef.
4) $ Apply daje ci sposób, kiedy chcesz to zrobić ręcznie , jak w przypadku zabezpieczenia przed awarią (w przypadku, gdy kliknięcie nie uruchamia się, wymuszasz jego uruchomienie).
W restauracji,
- CZEKAJ
mają przyjmować zamówienia od klientów, to jest
- MANAGER biegnie, aby upewnić się, że wszyscy kelnerzy nie śpią i reagują na wszelkie oznaki zmian ze strony klientów. To jest
$digest()
- WŁAŚCICIEL ma najwyższą moc, aby poprowadzić wszystkich na żądanie, to jest
$apply()
źródło