Czy ktoś może wyjaśnić w prosty sposób?
Dokumenty wydają się nieco tępe. Nie dostaję esencji i dużego obrazu tego, kiedy stosować jeden na drugim. Przykład kontrastujący z tymi dwoma byłby niesamowity.
javascript
angularjs
Numan Salati
źródło
źródło
Odpowiedzi:
funkcja kompilacji - służy do manipulacji szablonem DOM (tj. manipulacji elementem tElement = element szablonu), stąd manipulacje, które mają zastosowanie do wszystkich klonów DOM szablonu powiązanych z dyrektywą.
funkcja link - służy do rejestrowania detektorów DOM (tj. wyrażeń $ watch w zakresie instancji), a także manipulacji DOM instancji (tj. manipulacji iElement = indywidualny element instancji).
Jest wykonywany po sklonowaniu szablonu. Np. Wewnątrz <li ng-repeat ...> funkcja link jest wykonywana po sklonowaniu szablonu <li> (tElement) (do iElement) dla tego konkretnego elementu <li>.
$ Watch () pozwala powiadamiać dyrektywę o zmianach właściwości zasięgu instancji (zasięg instancji jest powiązany z każdą instancją), co pozwala dyrektywie na renderowanie zaktualizowanej wartości instancji do DOM - poprzez kopiowanie treści z zakresu instancji do DOM.
Należy zauważyć, że transformacji DOM można dokonać w funkcji kompilacji i / lub funkcji łączenia.
Większość dyrektyw wymaga tylko funkcji link, ponieważ większość dyrektyw dotyczy tylko określonej instancji elementu DOM (i zakresu jej instancji).
Jeden ze sposobów, aby pomóc określić, którego użyć: rozważ, że funkcja kompilacji nie otrzymuje
scope
argumentu. (Celowo ignoruję argument funkcji łączącej transkluzję, który otrzymuje zakryty zakres - jest to rzadko używane). Tak więc funkcja kompilacji nie może zrobić niczego, co chcesz zrobić, co wymaga zakresu (instancji) - możesz nie oglądaj żadnych właściwości zakresu modelu / instancji, nie możesz manipulować DOM przy użyciu informacji o zakresie instancji, nie możesz wywoływać funkcji zdefiniowanych w zakresie instancji itp.Jednak funkcja kompilacji (podobnie jak funkcja link) ma dostęp do atrybutów. Jeśli więc manipulacje DOM nie wymagają zasięgu instancji, możesz użyć funkcji kompilacji. Oto przykład dyrektywy, która z tych powodów używa tylko funkcji kompilacji. Bada atrybuty, ale nie potrzebuje zasięgu instancji do wykonania swojej pracy.
Oto przykład dyrektywy, która również używa tylko funkcji kompilacji. Dyrektywa musi jedynie przekształcić szablon DOM, aby można było użyć funkcji kompilacji.
Kolejny sposób, aby pomóc określić, którego użyć: jeśli nie użyjesz parametru „element” w funkcji link, prawdopodobnie nie potrzebujesz funkcji link.
Ponieważ większość dyrektyw ma funkcję link, nie podam żadnych przykładów - powinny być bardzo łatwe do znalezienia.
Zauważ, że jeśli potrzebujesz funkcji kompilacji i funkcji link (lub funkcji poprzedzających i post link), funkcja kompilacji musi zwrócić funkcje link, ponieważ atrybut „link” jest ignorowany, jeśli atrybut „compile” jest zdefiniowany.
Zobacz też
źródło
if you don't use the "element" parameter in the link function, then you probably don't need a link function.
czy masz na myśli „zakres” zamiast „elementu”?Przez kilka dni uderzam głową o ścianę i wydaje mi się, że lepiej wyjaśnić trochę więcej.
Zasadniczo, doktorzy wspominają, że separacja jest w dużej mierze poprawą wydajności. Chciałbym powtórzyć, że faza kompilacji jest używana głównie, gdy trzeba zmodyfikować DOM PRZED skompilowaniem samych podelementów.
Dla naszych celów podkreślę terminologię, która w innym przypadku jest myląca:
Usługa kompilatora (kompilacja $) jest mechanizmem kątowym, który przetwarza DOM i uruchamia różne bity kodu w dyrektywach.
FUNKCJA kompilacji to jeden fragment kodu w dyrektywie, który jest uruchamiany w określonym czasie przez USŁUGĘ kompilatora (kompilacja $).
Kilka uwag na temat kompilacji FUNKCJI:
Nie możesz modyfikować elementu ROOT (tego, na który wpływa twoja dyrektywa), ponieważ jest on już kompilowany z poziomu zewnętrznego DOM (kompilacja SERVICE już przeskanowała w poszukiwaniu dyrektyw dotyczących tego elementu).
Jeśli chcesz dodać inne dyrektywy do (zagnieżdżonych) elementów, możesz:
Muszę je dodać podczas fazy kompilacji.
Muszę wstrzyknąć usługę kompilacji do fazy łączenia i ręcznie skompilować elementy. ALE, uważaj na kompilację czegoś dwa razy!
Pomocne jest również sprawdzenie, jak działają zagnieżdżanie i jawne wywołania do kompilacji $, więc stworzyłem plac zabaw do oglądania na http://jsbin.com/imUPAMoV/1/edit . Zasadniczo rejestruje tylko kroki do pliku console.log.
Podam tutaj wyniki tego, co zobaczysz w tym koszu. W przypadku DOM dyrektyw niestandardowych tp i sp zagnieżdżone w następujący sposób:
Kompilacja kątowa SERVICE wywoła:
Kod jsbin ma również FUNKCJA post-link tp jawnie wywołuje usługę kompilacji SERVICE na trzeciej dyrektywie (w górę), która wykonuje wszystkie trzy kroki na końcu.
Teraz chcę przejść przez kilka scenariuszy, aby pokazać, jak można korzystać z kompilacji i łącza do robienia różnych rzeczy:
SCENARIUSZ 1: Dyrektywa jako MAKRO
Chcesz dynamicznie dodać dyrektywę (powiedzmy ng-show) do czegoś w swoim szablonie, które możesz uzyskać z atrybutu.
Załóżmy, że masz szablonUrl, który wskazuje na:
i chcesz niestandardowej dyrektywy:
co zmienia DOM w to:
w zasadzie chcesz zredukować płytę kotłową, mając pewną spójną strukturę modelu, którą twoja dyrektywa może interpretować. Innymi słowy: chcesz makro.
Jest to świetne zastosowanie w fazie kompilacji, ponieważ możesz oprzeć wszystkie manipulacje DOM na rzeczach, które znasz tylko z atrybutów. Wystarczy użyć jQuery, aby dodać atrybuty:
Sekwencja operacji będzie (możesz to zobaczyć za pomocą jsbin wspomnianego wcześniej):
W powyższym przykładzie nie jest wymagane łączenie, ponieważ cała praca dyrektywy została wykonana w kompilacji FUNKCJA.
W dowolnym momencie kod w dyrektywie może prosić o uruchomienie usługi kompilatora na dodatkowych elementach.
Oznacza to, że możemy zrobić dokładnie to samo w funkcji linku, jeśli wstrzykniesz usługę kompilacji:
Jeśli masz pewność, że elementy, które przekazujesz do $ compile SERVICE pierwotnie były wolne od dyrektyw (np. Pochodzą z szablonu, który zdefiniowałeś, lub właśnie utworzyłeś je za pomocą angular.element ()), to wynik końcowy jest prawie całkiem tak samo jak poprzednio (choć możesz powtarzać niektóre prace). Jeśli jednak element zawierał inne dyrektywy, spowodowałeś, że zostały one ponownie przetworzone, co może powodować różnego rodzaju nieprawidłowe zachowania (np. Podwójna rejestracja zdarzeń i zegarków).
Dlatego faza kompilacji jest znacznie lepszym wyborem do pracy w stylu makro.
SCENARIUSZ 2: Konfiguracja DOM za pomocą danych zakresu
Ten wynika z powyższego przykładu. Załóżmy, że potrzebujesz dostępu do zakresu podczas manipulacji DOM. W takim przypadku sekcja kompilacji jest dla ciebie bezużyteczna, ponieważ dzieje się to przed udostępnieniem zakresu.
Powiedzmy, że chcesz ulepszyć dane wejściowe za pomocą walidacji, ale chcesz wyeksportować swoje walidacje z klasy ORM po stronie serwera (DRY), i włączyć je automatycznie i wygenerować odpowiedni interfejs użytkownika po stronie tych walidacji.
Twój model może naciskać:
i możesz chcieć dyrektywy:
aby automatycznie dołączyć odpowiednie dyrektywy i div, aby pokazać różne błędy sprawdzania poprawności:
W takim przypadku zdecydowanie potrzebujesz dostępu do zakresu (ponieważ tam są przechowywane twoje walidacje) i będziesz musiał ręcznie skompilować dodatki, ponownie uważając, aby nie kompilować podwójnie. (na marginesie, musisz ustawić nazwę w tagu zawierającym formularz (zakładam, że tutaj jest formularz) i możesz uzyskać do niego dostęp w połączeniu z iElement.parent (). controller ('form'). $ name) .
W takim przypadku nie ma sensu pisać funkcji kompilacji. Link jest naprawdę tym, czego chcesz. Kroki byłyby następujące:
Tak jak:
Można oczywiście skompilować zagnieżdżone elementy jeden po drugim, aby uniknąć konieczności martwienia się o powielone przetwarzanie dyrektyw ng podczas ponownej kompilacji elementu najwyższego poziomu.
Ostatnia uwaga na temat tego scenariusza: zasugerowałem, że prześlesz definicję walidacji z serwera, aw moim przykładzie pokazałem je jako dane już w zakresie. Zostawiam to jako ćwiczenie dla czytelnika, aby dowiedzieć się, jak sobie poradzić z koniecznością pobierania tych danych z interfejsu API REST (wskazówka: odroczona kompilacja).
SCENARIUSZ 3: dwukierunkowe wiązanie danych przez łącze
Oczywiście najczęstszym zastosowaniem linku jest po prostu połączenie dwukierunkowego powiązania danych poprzez obejrzenie / zastosowanie. Większość dyrektyw zalicza się do tej kategorii, więc jest ona odpowiednio uwzględniona w innym miejscu.
źródło
Z dokumentów:
Tak więc przynajmniej w niektórych przypadkach dwie fazy istnieją osobno jako optymalizacja.
From @ UmurKontacı :
źródło
DOM
transformacji, powinno być,compile
jeśli chcesz dodać niektóre funkcje zmiany zachowania, powinno byćlink
.To z rozmowy Misko na temat dyrektyw. http://youtu.be/WqmeI5fZcho?t=16m23s
źródło
Trochę późno na wątek. Ale z korzyścią dla przyszłych czytelników:
Natknąłem się na następujący film, który wyjaśnia Compile and Link w Angular JS w bardzo świetny sposób:
https://www.youtube.com/watch?v=bjFqSyddCeA
Kopiowanie / pisanie wszystkich treści tutaj nie byłoby przyjemne. Z filmu zrobiłem kilka zrzutów ekranu, które wyjaśniają każdy etap faz kompilacji i łączenia:
Drugi zrzut ekranu jest nieco mylący. Ale jeśli zastosujemy numerację kroków, jest to całkiem proste.
Pierwszy cykl: „Kompilacja” wykonywana jest najpierw we wszystkich dyrektywach.
Drugi cykl: „Kontroler” i „Łącze wstępne” zostaje wykonany (tylko jeden po drugim) Trzeci cykl: „Łącze postowe” jest wykonywane w odwrotnej kolejności (zaczynając od środka)
Poniżej znajduje się kod, który pokazuje powyższe:
AKTUALIZACJA:
Część 2 tego samego wideo jest dostępna tutaj: https://www.youtube.com/watch?v=1M3LZ1cu7rw Film wideo wyjaśnia więcej na temat modyfikowania DOM i obsługi zdarzeń podczas procesu kompilacji i łączenia Angular JS, w prostym przykładzie .
źródło
compile
ipost
modyfikujący DOM przed jegotemplate
częściową modyfikacją na podstawie dyrektywy dostawcy.Dwie fazy: Kompilacja i połączenie
Skompilować:
Przejdź przez drzewo DOM w poszukiwaniu dyrektyw (elementy / atrybuty / klasy / komentarze). Każda kompilacja dyrektywy może modyfikować jej szablon lub modyfikować jej treść, która nie została jeszcze skompilowana. Po dopasowaniu dyrektywa zwraca funkcję łączenia, która jest używana w późniejszej fazie do łączenia ze sobą elementów. Pod koniec fazy kompilacji mamy listę skompilowanych dyrektyw i odpowiadających im funkcji łączenia.
Połączyć:
Kiedy element jest połączony, drzewo DOM jest łamane w punkcie rozgałęzienia w drzewie DOM, a zawartość jest zastępowana skompilowaną (i połączoną) instancją szablonu. Oryginalna wyparta zawartość jest odrzucana lub, w przypadku transkluzji, ponownie powiązana z szablonem. W przypadku transkluzji dwa elementy są z powrotem połączone (coś w rodzaju łańcucha, z kawałkiem szablonu znajdującym się na środku). Po wywołaniu funkcji link szablon został już powiązany z zakresem i dodany jako element potomny elementu. Funkcja linku jest okazją do dalszej manipulacji DOM i nasłuchiwania zmian konfiguracji.
źródło
To pytanie jest stare, chciałbym zrobić krótkie podsumowanie, które może pomóc:
źródło