Mam funkcję w moim kontrolerze kątowym, chciałbym, aby ta funkcja była uruchamiana na dokumencie gotowym, ale zauważyłem, że funkcja kątowa uruchamia ją podczas tworzenia domeny.
function myController($scope)
{
$scope.init = function()
{
// I'd like to run this on document ready
}
$scope.init(); // doesn't work, loads my init before the page has completely loaded
}
Czy ktoś wie, jak sobie z tym poradzić?
javascript
angularjs
onload
foreyez
źródło
źródło
$document
użyć zastrzyku, aby go użyć.angular.element
działa od razu po wyjęciu z pudełka.document
jest zmienną globalną, w której$document
można ją wstrzykiwać pod kątem, co ułatwia testowanie. Zasadniczo trudno jest testować aplikacje, które uzyskują dostęp do globalnych zmiennych JS, takich jak dokument lub okno. Myślę też, żemodule.run
to dobre miejsce na umieszczenie tego kodu zamiast kontrolera.Zobacz ten post Jak wykonać funkcję kontrolera kątowego przy ładowaniu strony?
Do szybkiego wyszukiwania:
W ten sposób nie musisz czekać, aż dokument będzie gotowy.
źródło
https://docs.angularjs.org/guide/bootstrap
Oznacza to, że kod kontrolera będzie działał, gdy DOM będzie gotowy.
Więc to jest po prostu
$scope.init()
.źródło
DOMContentLoaded
Jest również uruchamiany, gdy dokument został całkowicie załadowany i przeanalizowany, bez oczekiwania na zakończenie ładowania arkuszy stylów, obrazów i podramek. Aby uzyskać więcej informacji, zobacz Jaka jest różnica między zdarzeniem DOMContentLoaded a ładowaniem? .Angular ma kilka punktów czasowych, aby rozpocząć wykonywanie funkcji. Jeśli szukasz czegoś takiego jak jQuery
Ten analog może być bardzo przydatny:
Ten jest pomocny, gdy chcesz manipulować elementami DOM. Zacznie działać dopiero po załadowaniu wszystkich elementów.
UPD: To, co powiedziano powyżej, działa, gdy chcesz zmienić właściwości css. Czasami jednak nie działa, gdy chcesz zmierzyć właściwości elementu, takie jak szerokość, wysokość itp. W takim przypadku możesz spróbować:
źródło
Miałem podobną sytuację, w której musiałem wykonać funkcję kontrolera po załadowaniu widoku, a także po załadowaniu, zainicjowaniu określonego komponentu innej firmy w widoku i umieszczeniu odwołania do siebie na $ scope. To, co skończyło się dla mnie działaniem, to ustawienie zegarka na tej właściwości zakresu i uruchamianie mojej funkcji dopiero po jej zainicjowaniu.
Obserwator jest wywoływany kilka razy z nieokreślonymi wartościami. Następnie, gdy siatka jest tworzona i ma oczekiwaną właściwość, można bezpiecznie wywołać funkcję inicjalizacji. Przy pierwszym wywołaniu obserwatora z nieokreśloną newValue, oldValue nadal będzie niezdefiniowana.
źródło
Oto moja próba użycia zewnętrznego kontrolera za pomocą coffeescript. Działa raczej dobrze. Pamiętaj, że settings.screen.xs | sm | md | lg są wartościami statycznymi zdefiniowanymi w nieglifikowanym pliku, który dołączam do aplikacji. Wartości są zgodne z oficjalnymi punktami przerwania Bootstrap 3 dla tytułowych rozmiarów zapytań o media:
źródło
Odpowiedź
jest jedynym, który działa w większości testowanych przeze mnie scenariuszy. Na przykładowej stronie z 4 komponentami, z których wszystkie tworzą HTML z szablonu, kolejność zdarzeń była następująca
Zatem $ document.ready () jest w większości przypadków bezużyteczny, ponieważ DOM konstruowany pod kątem może nie być prawie gotowy.
Ale co ciekawsze, nawet po uruchomieniu $ viewContentLoaded nie można było znaleźć elementu zainteresowania.
Dopiero po wykonaniu limitu czasu $ został znaleziony. Zauważ, że chociaż wartość limitu czasu $ była równa 0, upłynęło prawie 200 milisekund, zanim zostało wykonane, co wskazuje, że ten wątek został wstrzymany na dłuższą chwilę, prawdopodobnie gdy DOM miał szablony kątowe dodane do głównego wątku. Całkowity czas od pierwszego $ document.ready () do ostatniego $ timeout wyniósł prawie 500 milisekund.
W jednym wyjątkowym przypadku, w którym ustawiono wartość komponentu, a następnie wartość text () zmieniono później w limicie czasu $, wartość limitu czasu $ musiała być zwiększana aż do zadziałania (nawet jeśli element można było znaleźć podczas limitu czasu $ ). Coś asynchronicznego w komponencie innej firmy spowodowało, że wartość miała pierwszeństwo przed tekstem, dopóki nie minęło wystarczająco dużo czasu. Inną możliwością jest $ scope. $ EvalAsync, ale nie został wypróbowany.
Nadal szukam tego jednego wydarzenia, które mówi mi, że DOM całkowicie się ustabilizował i można nim manipulować, aby wszystkie przypadki działały. Jak dotąd konieczna jest dowolna wartość limitu czasu, co oznacza, że w najlepszym wypadku jest to kludge, która może nie działać w wolnej przeglądarce. Nie próbowałem opcji JQuery, takich jak liveQuery i publikować / subskrybować, które mogą działać, ale z pewnością nie są czysto kątowe.
źródło
Jeśli dostajesz coś podobnego
getElementById call returns null
, to prawdopodobnie dlatego, że funkcja jest uruchomiona, ale identyfikator nie miał czasu na załadowanie do DOM.Spróbuj użyć odpowiedzi Willa (u góry) z opóźnieniem. Przykład:
źródło
Dlaczego nie spróbować z tym, co wspominają dokumenty kątowe https://docs.angularjs.org/api/ng/function/angular.element .
Użyłem tego w mojej funkcji $ onInit () {...}.
To zadziałało dla mnie.
źródło
źródło