2017-02-10 11 views
-1

は私が...機能が完了するまでに角度2 * ngが表示されないのはなぜですか?

// Pug Template 
.notification-header-area.layout-row.layout-align-center-center(*ngIf="notification.message != null", class="{{notification.color}}") 

// Inside angular component 
private onNotificationStart = (notification) => { 
     this.notification = notification; 
     console.log(this.myElement.nativeElement); 
     if (this.myElement.nativeElement.children.length > 0) { 
      // TODO: We should probably do this in a more reliable way in case the template changes. 
      let elm = this.myElement.nativeElement.children[0]; 
      if (notification.fontSize) elm.style.fontSize = notification.fontSize; 
      if (notification.colorBackground) elm.style.backgroundColor = notification.colorBackground; 
      if (notification.colorFont) elm.style.color = notification.colorFont; 
     } 
} 

を次のコードを持っている問題は、私は、コンソールラインでデバッグする場合は、ブラウザが通知DOM要素を示していないです。 console.logステートメントには、オブジェクトを書き出すときにもそのステートメントがありません。関数が実行を完了すると、ngIfがレンダリングされ、要素が期待どおりに表示されます。 $タイムアウトに相当するものがありますか?私はこのイベントをWebソケットから取得しており、Trouble with *ngIf in Angular 2 (TypeScript)を試しましたが、動作しませんでした。私はまた、私のシンプルなプランナー(Webソケットを使用していない)で再作成できなかったので、私はまだデモを探しています。

また、私は...それは動作します。このようなタイムアウトで折り返す場合

private onNotificationStart = (notification) => { 
    this.notification = notification; 
    setTimeout(() => { 
     console.log(this.myElement.nativeElement); 
     if (this.myElement.nativeElement.children.length > 0) { 
      // TODO: We should probably do this in a more reliable way in case the template changes. 
      let elm = this.myElement.nativeElement.children[0]; 
      if (notification.fontSize) elm.style.fontSize = notification.fontSize; 
      if (notification.colorBackground) elm.style.backgroundColor = notification.colorBackground; 
      if (notification.colorFont) elm.style.color = notification.colorFont; 
     } 
    }) 
    // if(notification){ 
    //  this.myElement.nativeElement.style.backgroundColor = 
    // } 
} 
+0

私は質問や問題が何かを得ることはありません。期待される行動は何ですか? –

+1

なぜ "* ng機能が完了するまでレンダリングしない"という問題がありますか? –

+0

これには同じ問題はありませんhttps://plnkr.co/edit/E2o56qn4el7cniofwvZK?p=previewだから私のことは何ですか? – Jackie

答えて

1

短い答え:両方のケースですべてが期待どおりに動作します。あなたの期待が違うならば、彼らは間違っています。少し長く

...

あなたは、いくつかの魔法を行うのか、それを実行するブラウザより賢くする角度期待することはできません。 :)私たちが少し単純化すれば... Javascriptには常に実行スレッドが1つしかありません(Webワーカーを考慮しません)。関数内で通知フラグを変更すると、使用可能な実行スレッドのみがブロックされるため、関数が終了するまで外界に何も起こりません。その後、ある時点で、変更検出が開始され、すべてのビューの同期、コンポーネントの作成または破棄、その他すべての作業が実行されます。これがsetTimeout()で動作する理由です - それはすべてのものが起こる機会を与えます。

+0

なぜこれは同じ問題ではない、それは似ているはずですが、これは私が期待しているものです。 https://plnkr.co/edit/E2o56qn4el7cniofwvZK?p=preview – Jackie

+0

これはこのスニペットでも同様に機能します。あなたはちょうどあなたの期待について少し混乱しているようです。 –

1

Angular2(4)、addEventHandlerのような非同期のAPIにパッチを適用するzone.jsを使用しsetTimeout、...イベントやsetTimeoutまたは別の非同期APIコールが起こるたびハンドラメソッドが完了した後、角度の実行が検出を変更。変更検出により、ビュー(バインディング)が更新されます。 *ngIfが更新された場合も同様です。したがって、バインドされた変数が更新されたメソッドの終了後に*ngIfが更新されるのは、まさに期待される動作です。

更新

ウェブソケットAPIをzone.jsでカバーされない場合がありますので、おそらく外Angularsゾーンを実行しているコールバック。 あなたはprivate zone:NgZoneを注入し、

this.zone.run(() => wrapped code here) 

またはprivate cdRef:ChangeDetectorRefを注入し、バインドされたフィールドを明示的に変化検出を起動するために更新された後

this.cdRef.detectChanges(); 

を呼んでコードをラップすることができます。

+0

ウェブソケットでの実験を正しく覚えていれば、zone.jsでカバーされているので、このようなものにラップする必要はありません。ポイントは、OPはsetTimeout()を使用する必要があるということです。 zone.run()の中で何かを実行しても、AngleはngZoneのすべてのタスクが完了するのを待ってから、変更検出とそのすべての処理を開始するので、助けにならないでしょう。 –

関連する問題