AngularJS でサードパーティ ツールや外部の DOM イベントを処理する際に留意すべき主な点の 1 つは、$scope.$apply()
メソッド操作を使用して変更を開始することです。これは驚くほど機能しますが、スコープ自体がすでにダイジェストをすりつぶしていて (これは基本的に $apply メソッドがトリガーするものです)、これが行われているときに $apply を呼び出すとエラーがスローされることがあります。$scope.$$phase
したがって、これを回避するには、ダイジェストが行われるたびにスコープに設定されるフラグに注意を払う必要があります。
ここで、URL を変更したいとします。
$scope.$apply(function() {
$location.path('/home');
});
これは期待どおりに機能しますが、ここで $scope がビジー状態であると仮定しましょう。そのため、代わりに $$phase 変数を確認し、変更が反映されると想定します。
if($scope.$$phase) {
$location.path('/home');
}
else {
$scope.$apply(function() {
$location.path('/home');
});
}
これは私が行ってきたことであり (明らかにコードの重複ではありません)、100% の時間で動作するようです。私が懸念しているのは、スコープが消化の途中にあるときに、AngularJS がどのように変更を取得するかということです。
おそらく、この例は十分に具体的ではありません。代わりにもっと大きなものを想定しましょう。大量のバインディングがあり、消化がページを直線的に消化すると仮定できる巨大な Web ページがある場合を想像してみてください (優先順位に関してこのようなことを行うと仮定しています ... この場合、最初に DOM ツリー)、ページのバインディングを上から下に更新します。
<div class="binding">{{ binding1 }}</div>
<div class="binding">{{ binding2 }}</div>
<div class="binding">{{ binding3 }}</div>
<div class="binding">{{ binding4 }}</div>
<div class="binding">{{ binding5 }}</div>
<div class="binding">{{ binding6 }}</div>
<div class="binding">{{ binding7 }}</div>
<div class="binding">{{ binding8 }}</div>
消化が進行中で、それが消化キューのほぼ中央にあると仮定しましょう。ここで、ページの上部にあるバインディングの値をどこかで変更してみましょう。
if($scope.$$phase) {
$scope.binding1 = 'henry';
}
どういうわけか、AngularJS は変更を取得し、バインディングを適切に更新します。変更自体は、HTML/DOM に関してキューの早い段階で行われると見なすことができますが。
私の質問は、AngularJS がこの潜在的な競合状態をどのように管理するかということです。binding8が更新された場合 (ページの下部にあるため)は多少快適ですが、 binding1も更新されるため ($apply を再度呼び出す必要なしにすぐに)、少し迷ってしまいます。これは、別の消化がその間のどこかに派遣されたことを意味しますか? それとも、$scope オブジェクトは私が予想するよりも魔法のようなものですか? この問題は以前からあったと思いますが、そもそも $$phase と $scope を見つけるのが少し難しいので、これも見過ごされた可能性があると思います。
何か案は?