$ postLink komponentu/dyrektywy kątowej uruchomiono zbyt wcześnie
Aktualizacja:
Przydzieliłem nagrodę za to pytanie. Nie szukam hacków ani obejść. Szukam oficjalnego sposobu na dostęp do domeny w komponencie kątowym i wyjaśnienie, dlaczego zachowanie, które widzę ($ postLink działa przed rozpoczęciem) wydaje się być sprzeczne z oficjalną dokumentacją.
Oficjalne dokumenty określają (
tutaj
https://docs.angularjs.org/guide/component
):
$ postLink () - wywoływana po połączeniu tego elementu kontrolera i jego elementów podrzędnych. Podobnie jak funkcja post-link, ten punkt zaczepienia może być używany do konfigurowania procedur obsługi zdarzeń DOM i wykonywania bezpośrednich manipulacji DOM
Oryginalne pytanie:
Mam tutaj przykład problemu - & >
http://plnkr.co/edit/rMm9FOwIm ... eview
http://plnkr.co/edit/rMm9FOwIm ... eview
Używam komponentu kątowego i chcę zmienić dom w funkcji łącza posta, ale to nie działa, wygląda na to, że funkcja działa zbyt wcześnie, zanim szablon będzie faktycznie gotowy w dom po całym przetwarzaniu kątowym.
Na stronie html mam to:
<my-grid grid-id="'foo'"></my-grid>
Składnik definiuje się jako:
appModule.component('myGrid',{
controller: gridController,
bindings: {
"gridId": "<",
},
templateUrl: 'gridTemplate'
});
W moim szablonie komponentów mam to:
<table id='{{$ctrl.gridId}}'>...
(Sam wiążący działa, nie ma wątpliwości co do tego. W końcu, w HTML, identyfikator tabeli jest "foo", zgodnie z oczekiwaniami).
W moim kontrolerze mam coś takiego:
function gridController($scope, $compile, $attrs) {
console.log ("grid id is: " + this.gridId);// 'foo' this.$postLink = function() {
var elem = document.getElementById(this.gridId);
// do something with elem, but elem is null
}
}
Podczas debugowania widzę, że po wykonaniu funkcji $ postLink tabela znajduje się w domenie, ale jej atrybut id nadal ma wartość
{{$ ctrl.gridId}}zamiast
foo, więc
document.getElementById ()niczego nie znajduje. Wydaje się, że jest to sprzeczne z dokumentacją.
czego mi brakuje? Czy istnieje inny sposób uzyskania dostępu do domeny w komponencie? [/code]
Aktualizacja 2:
Dzisiaj zdałem sobie sprawę, że ten sam problem występuje z normalną funkcją linku dyrektywy, nie jest on ograniczony do komponentów. Najwyraźniej źle zrozumiałem znaczenie „bezpośredniej manipulacji DOM” - funkcja link działa na elemencie oddzielnym od domeny, więc używanie obiektu
documentz selektorami jest bezużyteczne.
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
3 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Każde zdarzenie cyklu życia kontrolera/dyrektywy jest wywoływane wewnątrz $ apply, więc DOM jest aktualizowany tylko w celu odzwierciedlenia późniejszych zmian
koniec cyklu
https://docs.angularjs.org/gui ... -loop
$digest .
Funkcja linku do posta jest uruchamiana po połączeniu wszystkiego, ale dokładnie
na końcu tej funkcji
http://odetocode.com/blogs/sco ... .aspx
DOM jest aktualizowany w celu odzwierciedlenia wszelkich powiązań, ponieważ jest to ostatnia funkcja uruchamiana wewnątrz pętli $ digest. Oznacza to, że próba wysłania zapytania do DOM o cokolwiek, na co ma wpływ powiązanie, nie zadziała (np. lub, w twoim przypadku, wartość związana). Ale jak mówią dokumenty, powiązanie DOM już działa, więc oryginalny szablon jest tworzony i można go modyfikować.
Ponieważ musisz zażądać DOM po zastosowaniu Bindings, musisz uruchomić kod po zakończeniu bieżącego cyklu $ digest. Oznacza to używanie z opóźnieniem 0, co spowoduje
wykonywane natychmiast po zakończeniu bieżącego cyklu
http://blog.brunoscopelliti.co ... ring/
$digest .
Anonimowy użytkownik
Potwierdzenie od:
odosobniony
region. Powtarzam
jednostka
Tom
Więc,
Zgodnie z oficjalnym dokumentem [1.5.6] dotyczącym komponentów
https://docs.angularjs.org/guide/component
https://docs.angularjs.org/guide/component
Kiedy nie używać komponentów
:
- dla dyrektyw, które opierają się na manipulacji DOM, dodawaniu detektorów zdarzeń itp., ponieważ funkcje kompilacji i łączenia nie są dostępne
- gdy potrzebujesz zaawansowanych opcji definicji dyrektyw, takich jak priorytet, terminal, wieloelementowa
- jeśli potrzebujesz dyrektywy, która jest wyzwalana przez atrybut lub klasę CSS, a nie element
Jeśli spojrzysz na porównanie między definicją dyrektywy a sekcją dotyczącą definicji komponentu w dokumencie, zobaczyszTeraz
Komponenty nigdy nie powinny modyfikować żadnych danych ani DOM poza nimi
posiadać
obszary
działania . Zwykle w Angular możesz zmieniać dane
w dowolnym miejscu aplikacji przy użyciu dziedziczenia
obszary
działania i obserwacje. to
praktyczne, ale może również prowadzić do problemów, gdy nie jest jasne, które
część aplikacji odpowiada za modyfikację danych. Tutaj
dlaczego dyrektywy składników używają
odosobniony
zakres, więc cała klasa
manipulacja zakresem nie jest możliwa.
REF
:
NG-doc 1.5.6
Ale kiedy widzisz, że istnieje hak reklamy $ postLink (), możesz się zastanawiać, jaki jest tego powód?
Jeśli jednak przejrzysz opis tego haka, znajdziesz ...
Zapłacić
Zwróć uwagę, że elementy potomne zawierające
Dyrektywy templateUrl nie będą
skompilowane
i
połączony
ponieważ czekają na asynchroniczne załadowanie szablonu, a ich własna kompilacja i łączenie są wstrzymywane, dopóki to się nie stanie.
Proszę zapoznać się z odpowiedziami Stevena Lamberta poniżej ...
Anonimowy użytkownik
Potwierdzenie od:
jak większość wbudowanych dyrektyw
Angular .
Głównym problemem w twoim przypadku jest to, że chcesz wykonać manipulacje DOM po
interpolacje zostały skompilowane
lub jeszcze lepiej, gdy zarejestrowany obserwator zdąży raz wystrzelić.
Niestety,
oficjalny sposób
zrób to nie. Istnieją jednak sposoby, aby to zrobić, ale nie znajdziesz ich w dokumentacji.
Dwa popularne sposoby
uruchomienie funkcji po kompilacji interpolacji
:
W twoim przypadku znacznie lepiej jest użyć obserwatora do uruchomienia funkcji, gdy tylko istnieje element o podanym identyfikatorze:
Na koniec, moim zdaniem, uważam, że ilekroć trzeba czekać na kompilację interpolacji lub pewnych dyrektyw, aby wstawić ich wartość, nie stosuje się
Metoda budowania rzeczy
Kątowy. W twoim przypadku, dlaczego nie utworzyć nowego komponentu , który wymaga jako jego elementu nadrzędnego i dodać tam odpowiednią logikę. W ten sposób obowiązki każdego komponentu są znacznie lepiej zdefiniowane i łatwiejsze do zweryfikowania.