Różnica między funkcjami „kontrolera”, „łącza” i „kompilacji” podczas definiowania dyrektywy

393

Niektóre miejsca wydają się używać funkcji kontrolera do logiki dyrektywy, a inne używają linku. Przykład tabs na kątowej stronie głównej używa kontrolera dla jednej i linku do innej dyrektywy. Jaka jest różnica między nimi?

użytkownik1558259
źródło
2
Być może bardziej wszechstronny przegląd funkcji dyrektywy: Dyrektywy kątowe - kiedy używać kompilacji, kontrolera, pre-link i post-link .
Izhaki,

Odpowiedzi:

635

Rozbuduję trochę twoje pytanie i uwzględnię również funkcję kompilacji.

  • funkcja kompilacji - służy do manipulacji szablonem DOM (tj. manipulacji elementem tElement = element szablonu), a zatem do manipulacji, które mają zastosowanie do wszystkich klonów DOM szablonu powiązanych z dyrektywą. (Jeśli potrzebujesz także funkcji łącza (lub funkcji łącza poprzedzającego i post), a zdefiniowałeś funkcję kompilacji, funkcja kompilacji musi zwrócić funkcje link, ponieważ 'link'atrybut jest ignorowany, jeśli 'compile'atrybut jest zdefiniowany.)

  • funkcja link - zwykle używana do rejestrowania wywołań zwrotnych odbiornika (tj. $watchwyrażeń w zakresie), a także do aktualizacji DOM (tj. manipulowanie iElement = indywidualny element instancji). Jest wykonywany po sklonowaniu szablonu. Np. Wewnątrz an <li ng-repeat...>, funkcja link jest wykonywana po <li>sklonowaniu szablonu (tElement) (do iElement) dla tego konkretnego <li>elementu. A $watchpozwala na powiadamianie dyrektywy o zmianach właściwości zasięgu (zakres jest powiązany z każdą instancją), co pozwala dyrektywie renderować zaktualizowaną wartość instancji do DOM.

  • funkcja kontrolera - musi być używana, gdy inna dyrektywa wymaga interakcji z tą dyrektywą. Na przykład na stronie głównej AngularJS dyrektywa panelu musi dodać się do zakresu obsługiwanego przez dyrektywę tabs, stąd dyrektywa tabs musi zdefiniować metodę kontrolera (think API), do której dyrektywa panelu może uzyskać dostęp / wywołać.

    Aby uzyskać bardziej szczegółowe wyjaśnienie dyrektyw tabs i panel oraz dlaczego dyrektywa tabs tworzy funkcję na swoim kontrolerze przy użyciu this(a nie on $scope), zobacz 'this' vs $ scope w kontrolerach AngularJS .

Zasadniczo można umieszczać metody $watchesitp. W kontrolerze lub funkcji łącza dyrektywy. Sterownik uruchomi się jako pierwszy, co czasem ma znaczenie (zobacz to skrzypce, które loguje się, gdy funkcje ctrl i link działają z dwiema zagnieżdżonymi dyrektywami). Jak Josh wspomniał w komentarzu , możesz chcieć umieścić funkcje manipulowania zasięgiem wewnątrz kontrolera tylko dla zachowania spójności z resztą frameworka.

Mark Rajcok
źródło
131
Wyjaśnienie to powinno znajdować się w głównych dokumentach AngularJS lub przynajmniej w odniesieniu do niego
Dogoku,
7
To pouczająca odpowiedź, ale myślę, że trudno ją przeczytać. Być może więcej znaków interpunkcyjnych i mniejszych zdań może pomóc. Ogólnie jestem wdzięczny za odpowiedź.
Marty Cortez
Kompilator $ ignoruje atrybut „link” w obecności atrybutu „kompiluj”. A co z obecnością atrybutu „kontrolera”? Czy „kontroler” powoduje, że kompilator $ ignoruje jeden lub oba atrybuty „link” i „kompiluj”? Czy jest możliwe i / lub wskazane użycie „kompilacji” razem z „kontrolerem”?
Carl G
1
@CarlG, obecność atrybutu kontrolera nie ma wpływu na kompilator $ w odniesieniu do łącza i kompilacji. Możesz użyć kompilacji i kontrolera.
Mark Rajcok
1
„Słuchacze DOM” NIE są „(tzn. Wyrażenia $ watch w zakresie)”. Jeden nasłuchuje w DOM dla takich zdarzeń mouseover, a drugi w zakresie zmian właściwości. Duża różnica.
Dmitri Zaitsev,
56

Jako uzupełnienie odpowiedzi Marka, funkcja kompilacji nie ma dostępu do zakresu, ale funkcja łącza ma.

Naprawdę polecam ten film; Pisanie dyrektyw Misko Hevery'ego (ojca AngularJS), w którym opisuje różnice i niektóre techniki. (Różnica między funkcją kompilacji a funkcją linku o 14:41 na filmie ).

Pixic
źródło
3
+1 za link do filmu. To jest bardzo pouczające.
Rob Kielty
2
jvandemo.com/…
EMuentes
35
  1. uruchamianie kodu przed kompilacją: użyj kontrolera
  2. uruchamianie kodu po kompilacji: użyj łącza

Konwencja kątowa: zapisz logikę biznesową w kontrolerze i manipulację DOM w łączu.

Oprócz tego możesz wywołać jedną funkcję kontrolera z funkcji link innej dyrektywy. Na przykład masz 3 niestandardowe dyrektywy

<animal>
<panther>
<leopard></leopard>
</panther> 
</animal>

i chcesz uzyskać dostęp do zwierząt z wnętrza dyrektywy „lamparta”.

http://egghead.io/lessons/angularjs-directive-communication będzie pomocne, aby wiedzieć o komunikacji między dyrektywami

Rahul
źródło
18
„uruchamianie kodu przed kompilacją: użyj kontrolera”. To jest niepoprawne; compilezawsze będzie wykonywane wcześniej controller .
Izhaki,
Nie będziesz (przynajmniej nie w prosty sposób) uzyskać dostępu do zwierząt z dyrektywy w sprawie lampartów. Dyrektywy potomne mogą uzyskiwać dostęp do metod kontrolera w dyrektywie nadrzędnej, ale dyrektywy rodzeństwa (jak w powyższym przykładzie) nie mogą nawiązywać wzajemnie swoich kontrolerów.
Benjamin White
2
Czy lamparty naprawdę są rodzajem pantery? Na marginesie ... Czy możesz mieć link - ORAZ kontroler w dyrektywie?
Cody
1
tak, lampart / jaguary są panterami. i tak, masz link i kontroler w ramach dyrektywy.
Rahul
1
Z podręcznika programisty Angular: „Najlepsza praktyka: używaj kontrolera, gdy chcesz udostępnić interfejs API innym dyrektywom. W przeciwnym razie użyj łącza”.
Martin van Driel,
6

funkcja kompilacji -

  1. jest wywoływany przed kontrolerem i funkcją link.
  2. W funkcji kompilacji masz oryginalny szablon DOM, dzięki czemu możesz dokonywać zmian w oryginalnym DOM, zanim AngularJS utworzy jego instancję i zanim zostanie utworzony zakres
  3. ng-repeat jest doskonałym przykładem - oryginalna składnia to element szablonu, powtarzane elementy w HTML są instancjami
  4. Może istnieć wiele instancji elementu i tylko jeden element szablonu
  5. Zakres nie jest jeszcze dostępny
  6. Funkcja kompilacji może zwrócić funkcję i obiekt
  7. zwracanie funkcji (post-link) - jest równoważne z rejestracją funkcji łączenia za pomocą właściwości link obiektu config, gdy funkcja kompilacji jest pusta.
  8. zwracanie obiektu z funkcją (funkcjami) zarejestrowanymi za pomocą właściwości przed i po - pozwala kontrolować, kiedy funkcja łączenia powinna być wywoływana w fazie łączenia. Zobacz informacje o funkcjach wstępnego i późniejszego łączenia poniżej.

składnia

function compile(tElement, tAttrs, transclude) { ... }

kontroler

  1. wywoływany po funkcji kompilacji
  2. zakres jest dostępny tutaj
  3. mogą być dostępne przez inne dyrektywy (patrz atrybut wymagany)

link wstępny

  1. Funkcja link odpowiada za rejestrację detektorów DOM oraz aktualizację DOM. Jest wykonywany po sklonowaniu szablonu. W tym miejscu zostanie umieszczona większość logiki dyrektywy.

  2. Możesz zaktualizować dom w kontrolerze za pomocą angular.element, ale nie jest to zalecane, ponieważ element jest dostępny w funkcji link

  3. Funkcja wstępnego łączenia służy do implementacji logiki, która działa, gdy kątowy js skompilował już elementy potomne, ale zanim został wywołany jakikolwiek post link elementu potomnego

link do strony

  1. Dyrektywa, która ma tylko funkcję link, angular traktuje tę funkcję jak link do posta

  2. post zostanie wykonany po funkcji kompilacji, kontrolera i linku wstępnego, dlatego jest to uważane za najbezpieczniejsze i domyślne miejsce na dodanie logiki dyrektywy

Sunil Garg
źródło