Aufruf einer Funktion, wenn die ng-repeat beendet hat
Was ich versuche zu implementieren ist im Grunde ein "ng-repeat finished rendering" - handler. Ich bin in der Lage zu erkennen, Wann es fertig ist aber ich kann nicht herausfinden, so führen Sie eine Funktion aus.
Überprüfen Sie die Geige:http://jsfiddle.net/paulocoelho/BsMqq/3/
JS
var module = angular.module('testApp', [])
.directive('onFinishRender', function () {
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
element.ready(function () {
console.log("calling:"+attr.onFinishRender);
//CALL TEST HERE!
});
}
}
}
});
function myC($scope) {
$scope.ta = [1, 2, 3, 4, 5, 6];
function test() {
console.log("test executed");
}
}
HTML
<div ng-app="testApp" ng-controller="myC">
<p ng-repeat="t in ta" on-finish-render="test()">{{t}}</p>
</div>
Antwort:
Arbeiten Geige aus finishingmove: http://jsfiddle.net/paulocoelho/BsMqq/4/
Aus Neugier, was ist der Zweck der
Könnte man es mit built-in-Direktiven wie ng-init
Mögliche Duplikate von ng-repeat beenden-Ereignis
Duplikat von stackoverflow.com/questions/13471129/..., siehe meine Antwort dort
element.ready()
snippet? Ich meine.. ist es eine Art jQuery-plugin, das Sie haben, oder sollte es werden ausgelöst, wenn das element bereit ist?Könnte man es mit built-in-Direktiven wie ng-init
Mögliche Duplikate von ng-repeat beenden-Ereignis
Duplikat von stackoverflow.com/questions/13471129/..., siehe meine Antwort dort
InformationsquelleAutor PCoelho | 2013-03-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Merke, dass ich nicht verwenden
.ready()
sondern wickelte es in ein$timeout
.$timeout
stellt sicher, dass es ausgeführt wird, wenn die ng-wiederholte Elemente sind WIRKLICH fertig Rendern (weil die$timeout
ausführen wird am Ende der aktuellen digest-Zyklus -- und wird es auch nennen$apply
intern, im Gegensatz zusetTimeout
). So, nachdem dieng-repeat
beendet hat, verwenden wir$emit
zu emittieren, einer Veranstaltung, die zu den äußeren Bereichen (gleichgeordneten und übergeordneten Bereichen).Und dann in Ihrem controller, können Sie fangen Sie mit
$on
:Html, welches wie folgt aussieht:
Ich glaube, du bist verwirrend
$timeout
(das ist im GrundesetTimeout
+ Eckig ist$scope.$apply()
) mitsetInterval
.$timeout
wird nur einmal ausführen pro dieif
Zustand und werden zu Beginn des nächsten$digest
Zyklus. Für mehr info auf JavaScript-timeouts finden Sie unter: ejohn.org/blog/how-javascript-timers-workVielleicht habe ich etwas nicht verstehe 🙂 Aber sehen Sie, ich habe ng-repeat in einer anderen ng-repeat. Und ich möchte wissen, für sicher, wenn alle fertig sind. Wenn ich das script mit $timeout nur für übergeordnete ng-repeat hat alles Prima funktioniert. Aber wenn ich nicht verwenden, $timeout, ich bekomme eine Antwort, bevor Sie Kinder ng-Wiederholungen fertig sind. Ich will wissen, warum? Und kann ich sicher sein, dass wenn ich das script mit $timeout für Eltern-ng-repeat, ich werde immer eine Antwort bekommen, wenn alle ng-Wiederholungen fertig sind?
Warum würden Sie so etwas wie
setTimeout()
mit 0-delay eine andere Frage obwohl ich muss sagen, ich habe noch nie stoßen eine tatsächliche Angabe für den browser Ereignis-queue überall, nur was impliziert single-threadedness und die Existenz vonsetTimeout()
.Vielen Dank für diese Antwort. Ich habe eine Frage, warum müssen wir vergeben
on-finish-render="ngRepeatFinished"
? Wenn ich diesenon-finish-render="helloworld"
, es funktioniert auf die gleiche.InformationsquelleAutor holographic-principle
Verwenden $evalAsync wenn Sie möchten, dass Ihre callback (d.h., test()) ausgeführt, wenn das DOM aufgebaut ist, aber bevor der browser rendert. Dadurch wird verhindert flackern -- ref.
Fiddle.
Wenn Sie wirklich wollen, um Ihren Rückruf nach dem Rendern, verwenden Sie $timeout:
Ich lieber $eval anstelle eines Ereignisses. Mit einem event, müssen wir wissen, den Namen der Veranstaltung und hinzufügen von code, um unsere controller für das event. Mit $eval, es ist weniger die Kopplung zwischen der Steuerung und der Richtlinie.
$last
tun? Es nicht finden können in der Dokumentation. Wurde es entfernt?definiert den Anwendungsbereich, wenn ein
ng-repeat
aktiv auf das element.Sieht aus wie Ihre Geige ist die Aufnahme in eine unnötige
$timeout
.Toll. Dies sollte die akzeptierte Antwort, zu sehen, dass emittieren/broadcast-Kosten mehr, die aus performance-Sicht.
InformationsquelleAutor Mark Rajcok
Die Antworten, die bisher gegeben wurde, wird nur das erste mal funktioniert, dass die
ng-repeat
gerendert wird, aber wenn Sie haben eine dynamischeng-repeat
, was bedeutet, dass Sie werden das hinzufügen/löschen/filtern von Positionen, und Sie brauchen, um jedes mal benachrichtigt werden, dass dieng-repeat
gerendert wird, sind diese Lösungen nicht für Sie arbeiten.So, wenn Sie brauchen, um JEDES MAL benachrichtigt werden, dass die
ng-repeat
wird neu gerendert und nicht nur beim ersten mal, ich habe einen Weg gefunden, das zu tun, es ist sehr "hacky", aber es funktioniert gut, wenn Sie wissen, was Sie tun. Verwenden Sie diese$filter
in Ihremng-repeat
, bevor Sie alle anderen$filter
:Diese wird
$emit
eine Veranstaltung namensngRepeatFinished
jedes mal, dass dieng-repeat
gerendert wird., Wie es zu benutzen:
Den
ngRepeatFinish
filter muss direkt angewendet werden, um eineArray
oder eineObject
definiert in Ihrem$scope
haben, können Sie andere Filter nach., Wie es NICHT zu benutzen:
Gelten nicht für andere Filter zuerst und dann die
ngRepeatFinish
filter.Wann sollte ich verwenden?
Wenn Sie sich bewerben möchten bestimmte css-Stile in den DOM, nachdem die Liste fertig gerendert wird, weil Sie brauchen, um Berücksichtigung der neuen Dimensionen des DOM-Elemente wurden neu gerendert, die von der
ng-repeat
. (BTW: diese Art von Operationen durchgeführt werden sollte innerhalb einer Richtlinie)Was NICHT in der Funktion behandelt, die
ngRepeatFinished
Veranstaltung:Nicht eine
$scope.$apply
in diese Funktion oder setzen Sie Winkel in einer endlos-Schleife, die Winkel werden nicht in der Lage zu erkennen.Verwenden Sie es nicht für änderungen, die
$scope
Eigenschaften, da diese änderungen nicht sichtbar in der Ansicht, bis die nächste$digest
loop, und da Sie können nicht führen Sie eine$scope.$apply
Sie nicht von nutzen sein."Aber Filter sind nicht gedacht, um verwendet werden, so!!!!"
Nein, Sie sind nicht, dies ist ein hack, wenn Sie es nicht mögen, verwenden Sie es nicht. Wenn Sie wissen, einen besseren Weg, um das gleiche erreichen, bitte lassen Sie es mich wissen.
Zusammenfassung
Leider nicht für mich gearbeitet, zumindest für die Letzte AngularJS 1.3.7. So entdeckte ich eine andere Problemumgehung, nicht der schönste, aber wenn es wichtig für Sie, es wird funktionieren. Was ich getan habe ist, wenn ich hinzufügen/ändern/löschen von Elementen ich immer noch einen dummy-element am Ende der Liste, also seit
$last
element ist auch geändert, einfachngRepeatFinish
Richtlinie durch die überprüfung$last
jetzt funktioniert. Sobald ngRepeatFinish heißt ich Entferne dummy-Element. (Ich habe auch verstecken mit CSS, so dass es dooesn nicht kurz angezeigt)Funktioniert wunderbar, mit eckigen 1.3.15, danke
Sie sind falsch: jsfiddle.net/W8nhv/102
du hast Recht - wenn Elemente sind gespleißt/unshifted (d.h. das array wird mutiert), dann funktioniert es nicht. Meine bisherigen Tests war wahrscheinlich mit einem array, die zugewiesen wurde (mithilfe sugarjs) deshalb funktionierte es jedes mal... vielen Dank für diesen Hinweis
InformationsquelleAutor Josep
Wenn Sie brauchen, um verschiedene Funktionen aufrufen für verschiedene ng-Wiederholungen auf dem gleichen controller können Sie versuchen, so etwas wie dieses:
Der Richtlinie:
In Ihrem controller, catch-events mit $auf:
In Ihrer Vorlage mit mehreren ng-repeat
InformationsquelleAutor MCurbelo
Die anderen Lösungen funktionieren auf der ersten Seite zu laden, aber das aufrufen $timeout aus, der controller ist der einzige Weg, um sicherzustellen, dass Ihre Funktion wird aufgerufen, wenn das Modell sich ändert. Hier ist eine funktionierende fiddle verwendet, $timeout. Für dein Beispiel wäre das:
ngRepeat nur bewerten, eine Richtlinie, wenn Sie die Zeile Inhalt neu ist, so dass, wenn Sie entfernen Sie Elemente aus Ihrer Liste, onFinishRender wird nicht ausgelöst. Zum Beispiel, versuchen Sie, filtern Sie die Werte in diesen Geigen emittieren.
was ist
ta
im$scope.$watch("ta",...
?InformationsquelleAutor John Harley
Wenn Sie nicht abgeneigt, mit Doppel-dollar-Bereich Requisiten und schreiben Sie eine Richtlinie, deren einziger Inhalt eine Wiederholung, es ist eine ziemlich einfache Lösung (vorausgesetzt, Sie kümmert sich nur um die ersten render). In der link-Funktion:
Dies ist nützlich für Fälle, wo Sie eine Richtlinie, die Bedürfnisse zu tun, DOM-manip auf der Grundlage der breiten und Höhen der Mitglieder eines gerenderten Liste (und ich denke das ist der wahrscheinlichste Grund würde man diese Frage stellen), aber es ist nicht so generisch wie die anderen Lösungen, die vorgeschlagen wurden.
InformationsquelleAutor Semicolon
Einer Lösung für dieses problem mit einer gefilterten ngRepeat hätte mit Mutation Ereignisse, aber Sie sind veraltet (ohne sofortigen Ersatz).
Dann dachte ich an einen anderen einfach:
Dieser Haken in den Knoten.Prototypen Methoden des parent-Elements mit einem one-tick $timeout, auf die Sie achten aufeinander folgenden änderungen.
Klappt es meistens richtig, aber ich habe einige Fälle, in denen die altDone würde zweimal aufgerufen werden.
Wieder... fügen Sie diese Richtlinie an die Eltern der ngRepeat.
Was funktionieren könnte ist das hinzufügen
appendChild
als gut (da ich nurinsertBefore
undremoveChild
) in den obigen code.InformationsquelleAutor Sjeiti
Bitte haben Sie einen Blick auf die Fiedel, http://jsfiddle.net/yNXS2/. Da die Richtlinie, die Sie erstellt nicht erstellt einen neuen Bereich, die ich weiterhin in den Weg stellen.
$scope.test = function(){...
gemacht, dass passieren.humm, hast du das update der Geige? Ihr zeigt derzeit eine Kopie von meinem original-code.
InformationsquelleAutor Rajkamal Subramanian
Ich bin sehr überrascht, nicht zu sehen, die einfache Lösung unter den Antworten auf diese Frage.
Was Sie tun möchten, ist fügen Sie ein
ngInit
Richtlinie auf Ihre wiederholten element (das element mit derngRepeat
- Richtlinie) - Prüfung für$last
(eine spezielle variable gesetzt, im Rahmen vonngRepeat
was bedeutet, dass das wiederholte element ist das Letzte in der Liste). Wenn$last
ist wahr, wir Rendern das Letzte element und wir können die Funktion aufrufen, die wir wollen.Den kompletten code für Ihre HTML-markup wäre:
Brauchst du nicht extra JS code in Ihrer app neben der scope-Funktion, die Sie anrufen möchten (in diesem Fall
test
) seitngInit
wird zur Verfügung gestellt von Angular.js. Nur stellen Sie sicher, dass Ihretest
- Funktion in den Rahmen, so dass Sie zugegriffen werden kann von der Vorlage:InformationsquelleAutor Alejandro García Iglesias