2016-03-03 10 views
10

angle2テンプレートでネストされた非同期パイプがどのように解決されるかについて、私はちょっと混乱しています。ドキュメントは現在すぐれた場所ではありません。だから私は誰かが助けてくれることを望んでいます。ネストされたAngular2非同期パイプはどのように解決されますか?

私はサービスから返された非常に単純なRxjs ObservableをObservable.of(myArray).delay(2000)経由で持っています。遅延は、タイミングに関して何が起こっているかを示すのに役立ちます。私のテンプレートで

、私はちょうどそれが示されたときに制御する囲む<p>タグに上記返さ観測可能で非同期パイプを使用し、その<p>タグの内部で返される配列の長さを表示しようとしている:

<p *ngIf="!(lists | async)">Waiting for lists...</p> 
<p *ngIf="lists | async">We have lists! How many? => {{(lists | async)?.length}}</p> 

View the Plunker.

ですから、これをロードする際に、2秒後に私たちは「私たちは、リストを持っている!」を取得、表示される「リストを待っています」内部非同期パイプが解決され、配列の長さを解決するためにはもう2秒かかります。

Observableの値を返すことに依存する他のすべてのものと同時に表示するにはどうすればよいですか?それとも、これは非同期パイプの良いユースケースではないですか?代わりに私のコンポーネントの代わりにsubscribe()を使うべきですか?

答えて

10

非同期パイプは問題ありません。この問題には別のことがあります。

NgIfディレクティブのソースコードを確認してください。

条件が真の場合、ビューコンテナにビューが埋め込まれます。 ViewContainerRef#createEmbeddedView

ため

this._viewContainer.createEmbeddedView(this._templateRef); 

ドキュメントはtemplateRefに基づいて、埋め込みビューをインスタンス化し、指定されたインデックスでこの容器に挿入します。

基本的には、NgIf内にあるものをすべて取り込み、インスタンス化してDOMに配置します。

条件が偽の場合、それはDOMからすべてを削除し、ViewContainerRef#clear

のためのそれの内部すべてのビュー

this._viewContainer.clear(); 

ドキュメントはこのコンテナ内のすべてのビューを破棄クリアします。

NgIfが何をしているのか分かったので、どうしてこの現象が見られますか? lists結果がまだ到着していないこの時点で、これは実行されます。シンプルで、と私はそれがステップ

  1. <p *ngIf="!(lists | async)">Waiting for lists...</p>

    で説明します。

  2. <p *ngIf="lists | async":このngIfは2秒(設定した遅延時間)で実行されます。値が到着すると、NgIfディレクティブは内部にあるものをインスタンス化し、DOMに配置します。

  3. (lists | async)?.length:この非同期パイプは、2秒後に実行された後に実行されます。

だからあなたのタイムラインは、それはあなたがこの違いを参照してください理由ですそれ

*ngIf="lists | async" 
----(2 seconds)-----> 

        (lists | async)?.length 
        ------(2 seconds)-----> 
               print value 

(私は私の貧弱なタイムライン設計のための本当にすみません)このようになります。 *ngIf?.lengthと並行して実行されていません。

あなたはすぐにそれを見たい場合は、

// Template 
<p *ngIf="lists">We have lists! How many? => {{lists.length}} some value</p> 

// Observable 
this._listService.getLists(2000).subscribe(res => this.lists = res); 

を次のようにこれはもちろん、あなたの他の非同期のパイプに影響を与えるように自分自身をdelayオペレータを削除、または手動でサブスクライブし、値を設定する必要があります。あなたのコードを使ってこのplnkrを参照してください。

これが役立ち、少し明確になることを願っています。

+0

ありがとうございます。私の観測で 'delay()'を使うと '* ngIf'の仕組みについてもっと学ぶことができます:) – chucknelson

+6

ソースが観測可能であるという事実は決して*共有*されていないということも重要です。よくオリジナルのシナリオ 'lists'では、observableが2回(' ngIf'のために1回、次に 'length'のために)購読され、各サブスクリプション毎に遅延を含めてストリームが新たに開始されます。 'lists'が共有されたり、再生されたり、熱くなったりした場合、2番目のサブスクリプションは新しい遅延なしにすぐに最終的な配列値を見つけ出します。 – superjos

関連する問題