私は、Angularを一種の「安全な$ apply」メソッドとして$ timeoutサービスを使用することのニュアンスをよりよく理解しようとしています。基本的に、コードの一部がAngularイベントまたはjQueryや標準のDOMイベントなどの非角形イベントのいずれか。
私が物事を理解しているように:
Angularソースコードを見ると、$ timeoutが$ rootScope。$ apply()を呼び出しているように見えます。
洞察力をありがとう。
Angularソースコードを見ると、$ timeoutが$ rootScope。$ apply()を呼び出しているようです。
- ダイジェストサイクルが既に進行中の場合、$ timeout()もエラーを発生させないのはなぜですか?
$timeout
は、文書化されていないAngularサービス$browser
を使用します。具体的には、$browser.defer()
を使用して、関数の実行をwindow.setTimeout(fn, delay)
を介して非同期に延期します。これは常にAngularライフサイクルの外側で実行されます。 window.setTimeout
が一度起動すると、関数は$timeout
が$rootScope.$apply()
を呼び出します。
- ダイジェストがまだ進行中でないことが確実にわかっている場合は$ scope。$ apply()を使用し、どちらにしても安全である必要がある場合は$ timeout()を使用するのがベストプラクティスですか?
そう言うでしょう。別の使用例として、ダイジェスト後にのみ初期化されることがわかっている$ scope変数にアクセスする必要がある場合があります。シンプルな例は、コントローラーのコンストラクター内でフォームの状態をダーティに設定する場合です(何らかの理由で)。 $ timeoutがなければ、FormController
は初期化されず、$ scopeに公開されていないため、$scope.yourform.setDirty()
を$ timeout内にラップすると、FormController
が初期化されます。確かに、$ timeoutを使用せずにディレクティブを使用してこれらすべてを実行できます。別のユースケースの例を示します。
- $ timeout()は本当に許容できる「安全な適用」ですか、それとも落とし穴がありますか?
常に安全である必要がありますが、あなたのgo toメソッドは常に私の意見では$ apply()を目指すべきです。私が取り組んでいる現在のAngularアプリはかなり大きく、$ apply()の代わりに1回だけ$ timeoutに依存する必要がありました。
アプリケーションで$ applyを頻繁に使用すると、エラー:$ digestが既に進行中になる場合があります。一度に1つの$ digestサイクルを実行できるためです。 $ timeoutまたは$ evalAsyncで解決できます。
$ timeoutは、「$ digest already in progress」のようなエラーを生成しません。$ timeoutは、Angular=ダイジェストサイクル間の衝突と$ timeoutの出力は、新しい$ digestサイクルで実行されます。
私はそれらを説明しようとしました: apply、timeout、digest、evalAsyncの比較 。
役立つかもしれません。
私が理解する限り、$timeout
は$scope.$apply
を暗黙的に呼び出すsetTimeout
のラッパーです。つまり、angularライフサイクルの外側で実行されますが、キックスタートangularライフサイクル自体。私が考えることができる唯一の「落とし穴」は、結果が利用可能になると期待している場合this$digest
、「安全に適用」する別の方法を見つける必要があります(これは、$scope.$$phase
を介してのみ利用可能です)。