Ich habe eine Funktion in meinem Winkelcontroller. Ich möchte, dass diese Funktion dokumentbereit ausgeführt wird, aber ich habe festgestellt, dass Winkel sie beim Erstellen des Doms ausführt.
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
}
Weiß jemand, wie ich das machen kann?
javascript
angularjs
onload
foreyez
quelle
quelle
$document
, um es zu verwenden.angular.element
funktioniert sofort.document
ist eine globale Variable, bei der as$document
durch Winkel injizierbar ist und somit das Testen erleichtert. Im Allgemeinen ist es schwierig, Unit-Test-Anwendungen zu erstellen, die auf globale JS-Variablen wie Dokumente oder Fenster zugreifen. Ich denke auch, dass diesmodule.run
ein guter Ort ist, um diesen Code anstelle des Controllers einzufügen.Siehe diesen Beitrag Wie wird die Winkelreglerfunktion beim Laden der Seite ausgeführt?
Für eine schnelle Suche:
Auf diese Weise müssen Sie nicht warten, bis das Dokument fertig ist.
quelle
https://docs.angularjs.org/guide/bootstrap
Dies bedeutet, dass der Controller-Code ausgeführt wird, nachdem das DOM bereit ist.
So ist es einfach
$scope.init()
.quelle
DOMContentLoaded
ausgelöst, wenn das Dokument vollständig geladen und analysiert wurde, ohne darauf zu warten, dass Stylesheets, Bilder und Hilfsrahmen vollständig geladen sind. Weitere Informationen finden Sie unter Was ist der Unterschied zwischen DOMContentLoaded- und Ladeereignissen? .Angular hat mehrere Zeitpunkte, um Funktionen auszuführen. Wenn Sie nach etwas wie jQuery's suchen
Sie können dieses Analogon im Winkel sehr nützlich finden:
Dieser ist hilfreich, wenn Sie die DOM-Elemente bearbeiten möchten. Die Ausführung wird erst gestartet, nachdem alle te-Elemente geladen wurden.
UPD: Was oben gesagt wurde, funktioniert, wenn Sie die CSS-Eigenschaften ändern möchten. Manchmal funktioniert es jedoch nicht, wenn Sie die Elementeigenschaften wie Breite, Höhe usw. messen möchten. In diesem Fall möchten Sie möglicherweise Folgendes versuchen:
quelle
Ich hatte eine ähnliche Situation, in der ich eine Controller-Funktion ausführen musste, nachdem die Ansicht geladen wurde und nachdem eine bestimmte Komponente eines Drittanbieters in der Ansicht geladen, initialisiert und einen Verweis auf sich selbst in $ scope platziert hatte. Am Ende funktionierte es für mich, eine Überwachung für diese Scope-Eigenschaft einzurichten und meine Funktion erst nach der Initialisierung auszulösen.
Der Watcher wird mehrmals mit undefinierten Werten aufgerufen. Wenn das Raster erstellt wird und die erwartete Eigenschaft aufweist, kann die Initialisierungsfunktion sicher aufgerufen werden. Wenn der Watcher zum ersten Mal mit einem nicht undefinierten newValue aufgerufen wird, ist oldValue weiterhin undefiniert.
quelle
Hier ist mein Versuch innerhalb eines äußeren Controllers mit Coffeescript. Es funktioniert ziemlich gut. Bitte beachten Sie, dass settings.screen.xs | sm | md | lg statische Werte sind, die in einer nicht hässlichen Datei definiert sind, die ich in die App einbinde. Die Werte beziehen sich auf die offiziellen Bootstrap 3-Haltepunkte für die gleichnamigen Medienabfragegrößen:
quelle
Die Antwort
ist die einzige, die in den meisten von mir getesteten Szenarien funktioniert. Auf einer Beispielseite mit 4 Komponenten, die alle HTML aus einer Vorlage erstellen, war die Reihenfolge der Ereignisse
Daher ist ein $ document.ready () in den meisten Fällen nutzlos, da das im Winkel erstellte DOM möglicherweise noch lange nicht fertig ist.
Interessanter ist jedoch, dass das interessierende Element auch nach dem Auslösen von $ viewContentLoaded immer noch nicht gefunden werden konnte.
Erst nach dem ausgeführten $ timeout wurde es gefunden. Beachten Sie, dass, obwohl das $ timeout einen Wert von 0 hatte, fast 200 Millisekunden verstrichen sind, bevor es ausgeführt wurde, was darauf hinweist, dass dieser Thread eine Weile unterbrochen wurde, vermutlich während dem DOM eckige Vorlagen zu einem Hauptthread hinzugefügt wurden. Die Gesamtzeit von der ersten Ausführung von $ document.ready () bis zur letzten Ausführung von $ timeout betrug fast 500 Millisekunden.
In einem außergewöhnlichen Fall, in dem der Wert einer Komponente festgelegt und der Wert von text () später im $ timeout geändert wurde, musste der $ timeout-Wert erhöht werden, bis er funktionierte (obwohl das Element während des $ timeout gefunden werden konnte ). Durch etwas Asynchrones innerhalb der Komponente eines Drittanbieters hatte ein Wert Vorrang vor dem Text, bis genügend Zeit verstrichen war. Eine andere Möglichkeit ist $ scope. $ EvalAsync, wurde aber nicht ausprobiert.
Ich bin immer noch auf der Suche nach dem einen Ereignis, das mir sagt, dass sich das DOM vollständig beruhigt hat und manipuliert werden kann, damit alle Fälle funktionieren. Bisher ist ein beliebiger Timeout-Wert erforderlich, was bestenfalls bedeutet, dass dies ein Kludge ist, der in einem langsamen Browser möglicherweise nicht funktioniert. Ich habe keine JQuery-Optionen wie liveQuery und Publish / Subscribe ausprobiert, die möglicherweise funktionieren, aber sicherlich nicht rein eckig sind.
quelle
Wenn Sie so etwas erhalten
getElementById call returns null
, liegt dies wahrscheinlich daran, dass die Funktion ausgeführt wird, die ID jedoch keine Zeit zum Laden im DOM hatte.Versuchen Sie, Wills Antwort (nach oben) mit Verzögerung zu verwenden. Beispiel:
quelle
Warum nicht versuchen , mit dem, was Winkel docs erwähnen https://docs.angularjs.org/api/ng/function/angular.element .
Ich habe dies in meiner Funktion $ onInit () {...} verwendet.
Das hat bei mir funktioniert.
quelle
quelle