Als eine High-Level-Einführung würde ich sagen, dass es selten erforderlich ist, Ihren eigenen Digest-Zyklus tatsächlich zu initiieren, da eckig die meisten Fälle behandelt.
Lassen Sie uns auf die Frage eingehen.
Als sehr hohen Niveau, das verdauen $ sieht Schleife dies wie:
Do:
- - - If asyncQueue.length, flush asyncQueue.
- - - Trigger all $watch handlers.
- - - Check for "too many" $digest iterations.
While: (Dirty data || asyncQueue.length)
Also im Grunde $evalAsync
zum asyncQueue
die Funktion erweitert und defering ein verdauen, wenn sie ihn braucht. Wenn es jedoch bereits in einem Digest-Zyklus ist, wird es die asyncQueue
leeren und es wird nur die Funktion aufrufen.
Sie können feststellen, dass dies sehr ähnlich wie die safeApply
ist. Ein Unterschied besteht darin, dass die Funktion nicht zu der asyncQueue
hinzugefügt wird, sondern nur aufgerufen wird, was beispielsweise in der Mitte eines Zyklus passieren kann. Der andere Unterschied besteht darin, dass es eine $$
Variable exponiert, die intern sein soll.
Der wichtigste Unterschied aber zwischen $evalAsync
und $apply
von $digest
(Ich werde zu $timeout
unten bekommen) ist, dass $evalAsync
und $apply
am $rootScope
den Digest beginnt, aber sie rufen Sie die $digest
auf jedem Umfang. Sie müssen Ihren individuellen Fall bewerten, wenn Sie denken, dass Sie diese Flexibilität benötigen.
Die Verwendung von $timeout
ist wieder sehr ähnlich zu $evalAsync
, außer dass es es immer aus dem aktuellen Digest-Zyklus verschiebt, falls es einen gibt.
$timeout(function() {
console.log("$timeout 1");
});
$scope.$evalAsync(function($scope) {
console.log("$evalAsync");
});
Wenn Sie bereits in einem Digest-Zyklus geben Ihnen
$evalAsync
$timeout 1
Auch wenn sie in der entgegengesetzten Reihenfolge aufgerufen werden, da das Timeout einem zum nächsten verzögert Zyklus verdauen, die es instanziiert.
EDIT Für die Fragen in den Kommentar. Der größte Unterschied zwischen $apply
und $evalAsync
, soweit ich sagen kann, ist, dass $apply
tatsächlich den $digest
Zyklus auslöst. Für Sie bedeutet dies, dass Sie sicher sein müssen, dass Sie $apply
aufrufen, wenn Sie sich nicht in einem Digest-Zyklus befinden. Nur für Transparenz, ist der folgende Code gilt auch:
$scope.$apply(function() {
$scope.$evalAsync(function() {
});
});
, die die Anwendung Funktion aufrufen, die no-op-Funktion zum $asyncQueue
und den Digest-Zyklus beginnen. Die docs sagen, es wird empfohlen, $apply
zu verwenden, wenn sich das Modell ändert, was in Ihrem $evalAsync
Der Unterschied zwischen fn(); $scope.apply()
und $scope.apply(fn)
passieren könnte, ist nur, dass die $scope.apply(fn)
tut einen Versuch Fang für die Funktion und explizit verwendet $exceptionHandler
. Darüber hinaus könnten Sie tatsächlich versuchen, Digest-Zyklen in fn
zu verursachen, die ändern, wie die Anwendung behandelt wird.
Ich würde auch gerne auf diese Zeit hinweisen, dass es noch komplizierter ist in 1.3 vorausgesetzt, es bleibt so. Es wird eine Funktion namens $applyAsync
geben, die verwendet wird, um ankommende Anrufe zu verzögern (reference).
Dieser Beitrag zusammengestellt einige Informationen aus This blog und diese so post plus einige meiner Erfahrung.
Hoffe das half!
Dies ist eine sehr gute Frage, leider passt es wahrscheinlich nicht zum Format von Stack Overflow. – Sacho
Sehen Sie, ob dies hilft: http://www.sitepoint.com/understanding-angulars-apply-digest/ –
@Sacho Was meinst du? – Naor