Angular.js: 非同期module.run()をサポートする

作成日 2013年09月13日  ·  62コメント  ·  ソース: angular/angular.js

モジュール実行ブロックでいくつかの$ http呼び出しを発行したいのですが、理想的には、実行は$ httpの後でのみ終了し、処理はdomコンパイルが行われる前に終了する必要があります。

Lots of comments won't fix feature

最も参考になるコメント

jfcfxekzl5m
シンプルな機能ですが、実装が難しすぎます。 😕

全てのコメント62件

これはそれほど簡単ではありませんが、調査する必要があります。

Jasmineがこれを行う方法は、フラグを設定することです。これにより、関数が実行され、フラグがtrueに設定されるまで、またはタイムアウトが発生するまでコールバックが待機します。

基本的にこのようなもの:

var flag = false;
$http(...).success(flag = true);
$timeout(function () {
    flag = true;
    // Or add some error handling stuff here
}, 5000);
while (!flag) {};

それはきれいではありませんが、仕事をする必要があります。 上記のコードはテストされていないため、少し変更する必要があるかもしれません。 ここでは遅くなっています。 うまくいけば、少しきれいなものが来るまであなたを手に入れるための何か。

+1

しかし、一瞬で、これは角度ディレクティブを使用して派手なロード画面を描くことができなくなります...

+1

$routeProviderresolveこれを解決しませんか? 多分私は問題を理解していませんでした...

これは、非同期モジュールの初期化サポートのためのものです。 そうは言っても、現在のプロジェクトではこれはもう必要ありません。

@shahata $routeproviderはこれを行いますが、約束を与えるrunのすべてのユースケースがルートを使用するわけではありません。 私のユースケースでは、ディレクティブをラップし、ルートとは関係のないモジュール用です。

+1

run関数がpromiseを返すかどうかを確認し、解決されたときにのみ続行します。 runBlocksは関数の配列であるため、それほど難しいことではありません。

+1

これが無視されたことを恥ずかしい+1

これがいつ着陸するかについて何か考えはありますか? ルーターで解決するために初期化のものを移動しなければならないのはとてもイライラします。これは主に、初期化コードがURLに依存しない場合があるためです(つまり、ユーザーがSPAに到達するすべてのタイプのURLに対して初期化する必要があります)

今後、Angularが機能強化されることはないと思います。 それらはすべてAngular2.0に追加されています

中途半端なrunメソッドが同期を維持する期間はどれくらいですか? $http呼び出しを行うプロバイダーがないため、 configが非同期呼び出しをサポートしていないことは問題ありませんが、 runはサポートしています。 この機能の欠如(最初からあったはずの)が引き起こすハッキングの種類を見てください
https://github.com/philippd/angular-deferred-bootstrap/blob/master/src/deferred-bootstrap.js

恥ずかしいです

+1

@btfordは、これに関するユースケースが、実行ブロック内ではなく、新しいルーターを介してどのようにサポートされるかを検討しています。

+1

+1

+1

+1

私たちが抱えている主な問題は、runBlocksの実行時にロードされているモジュール内に$qが作成されることです。 つまり、何らかの方法でサービス(またはモジュール)の「一部」を抽出し、それらを最初に作成してから、$ qの後に残りのモジュール(およびサービス、実行ブロックなど)をロードする2番目のパスを作成する必要があります。作成されました。

@ lgalfaso-今週(または来週)の後半に$injector作業の一環として、これをもう少し詳しく調べることができますか?

私はそれが単なる回避策であることを知っていますが、私は通常、角度のあるuiルーターを使用し、resolveと組み合わせてルート抽象状態を持つことにより、非同期ブートストラップロジックを持つ問題を解決しました。 ルート抽象状態は常に最初に解決する必要があるため、設定をロードしたり、ロードアニメーションを表示したりするのに適した場所です。

これは本当に素晴らしいでしょう。
:+1:
この修正を待っています。 1.4で取得されることを願っています

+1

別のユースケースがあります:起動時に$ http呼び出しでシミュレートされたエンドポイントを初期化する必要があります(一部のデータをキャッシュするため)...

+1

+1

これにもつまずいた...

@petebacondarwin他のすべてのモジュールのロードを続行しても問題ないと思いますが、最初のナビゲーションの開始を延期します。

あるいは、$ routeProviderは、初期ルートのレンダリングを延期する構成可能な関数パラメーターを提供することもできます。

+1

+1

考えられる回避策は次のとおりです。http
Angularは、実際には一連のモジュールから独自のインジェクターを作成する機能を提供するという考え方です。 この場合、一連のプロミス( resolves )が解決されるまで、 $rootElementコンパイルを遅らせました。 これはPOCであり、このプロダクションを準備するために必要となる他の多くのベルやホイッスルがあります。 他のものとは別に、単にエラーを飲み込むのではなく、解決のエラーをキャッチする必要があります。

+1

これは主に、それを試してみたい人へのガイドです。 現在、ブートストラッププロセスは次のことを行います。

  • 健全性チェック
  • $rootElementのプロデュースを作成します
  • インジェクターを作成します
  • $rootElementコンパイルしてリンクします

さらに、インジェクターを作成するときの手順は次のとおりです。

  • 依存関係モジュールツリーをトラバースし、

    • モジュールの定数、値、プロバイダーなどを登録するモジュールの初期化

    • 設定関数の実行

    • 後で使用するためにrun関数を収集します

  • すべてのrun関数を実行します

重要なポイントがいくつかあります。

  • $rootElementがコンパイルされる前に、すべてのrunブロックが実行されます
  • インジェクター作成プロセスにはダイジェストサイクルはありません。最初のダイジェストサイクルは、 $rootElement最初のコンパイル中です。
  • $qは、ダイジェストサイクル中にpromiseを解決します_only_

これは:

  • promiseを返すrun関数を持つモジュールがあり、アプリを起動する前にpromiseを解決する必要がある場合、最初のコンパイルの前にダイジェストサイクルがあります(これにより既存のアプリが破損する可能性があります)
  • config関数がインスタンスではなくプロバイダーに注入されるため、構成ブロックはpromiseを返すことができません

どのような解決策でも、これらのケースを処理する必要があります

+1
連絡あった?
アプリが実際に起動する前に、いくつかの構成設定をロードしたいだけです。

+1

すべてのファクトリが稼働しているときのブートストラップの後、コンパイルする前に、いくつかの非同期データをロードします。

@dagingaa :回避策としてあなたの解決策を選ぶと思います! ありがとう

  • 1

@dagingaaへの更新:forループがブラウザーをフリーズします。

https://jsfiddle.net/tuxmachine/t4d63vnw/

これが、アプリの残りの部分を初期化する前に最初のajax呼び出しを解決する必要があるOAuthトークンの実装でそれを解決した方法です。

ただし、複数の非同期実行ブロックがある場合は機能しません

+1

+1

+1

発行から2年が経ちましたが、まだ良い解決策はありません

@vladmiller解決策はありますが、おそらくあなたはそれらが良いとは感じていません:

  • ngRouteまたはui-routerをresolvesで使用し、アプリケーションの起動コードを最上位ルート内に配置します
  • 独自の非同期ブートストラップを作成します。 https://github.com/angular/angular.js/issues/4003#issuecomment-113842180を参照して
  • トップレベルコンポーネントに$onActivateを含む新しいコンポーネントルーターを使用する

重要なアプリケーションの作業を.runブロック内に配置すると、コードの単体テストが困難になります。 ですから、それは私たちが奨励したいことではありません。 これを実装する可能性が低いものとしてアイスボックスに移動します。

@petebacondarwin私はあなたに同意しません。 誰もがangluarがシンプルで直感的であることを期待しています。代わりに、独自の非同期ブートストラップモジュールまたはブートストラップモジュールを別の場所に実装する必要があります。 私の意見では、これは角度をより複雑にします。

また、 .run非同期コードがテストをより困難にするという意味を説明できますか?

以前の失礼なコメントをお詫びします。
ありがとう

@petebacondarwinテストがどのように難しくなるのかわかりません。 初期化コードをサービスに配置すると、 .runブロック内で実行されているかどうかに関係なく、httpバックエンドモックから期待される結果を監視/モック/比較できます。 非同期実行がないための回避策のためにコードがAngularの外側に存在することが、テストをほぼ不可能にしている理由です。

どのようにそれが起こっている?

別のアプローチ: http

@petebacondarwinソリューションは私のために働いた

回避策があり、非同期実行ブロックをサポートするとブートストラップが複雑になるため、この機能を実装することはないと思います。

jfcfxekzl5m
シンプルな機能ですが、実装が難しすぎます。 😕

この機能の+1

+1

+1

@petebacondarwinソリューションはうまく機能します。

+1。 :(

+1

+1

+1

+1

これは行いません。

+100、すべての回避策はひどいです。

@ Eduardo-Julio-AngularJSアプリケーションのブートストラップがはるかに複雑になるため、この機能は実装しません。 さらに+追加しても効果はありません。

このページは役に立ちましたか?
0 / 5 - 0 評価