2017-06-17 11 views
0

Observable.interval(1000)を使用してコンストラクタで初期化しない限り、非同期パイプがオブザーバブルセットngAfterViewInit()にバインドされない状況があります。 .interval -partを削除すると、非同期パイプはngAfterViewInit()が実行されたときにobservableに登録されません。非同期パイプがObservableにアングルでバインドされない

私はクラスのトップで、このような観測を初期化したいと思いますが、それは機能を壊す:

resultStream: Observable<string>; 
genderStream: Observable<number>; 

私はこのように宣言する必要があります。

// Weird fix: I need to add .interval(?) for async pipe to work later on... 
resultStream: Observable<string> = Observable.interval(1000).map(() => ""); 
genderStream: Observable<number> = Observable.interval(1000); 

だから私の私は.interval()セットアップを使用しなければならないので、今や少し不満を感じています。

問題は、このplunkerで再現されています。https://plnkr.co/edit/q3TR5iszU1swFrTjajEa

は性別をクリックして、結果を表示するには、入力フィールドに整数を入力します。

簡単で洗練されたソリューションでこれを手伝ってもらえますか?おかげさまで

完全なクラスはこれです:

import { Component, OnInit, ViewChild, ElementRef, AfterViewInit, ChangeDetectionStrategy } from '@angular/core'; 
import { Observable } from 'rxjs/Rx'; 


@Component({ 
    selector: 'my-app', 
    template: ` 
    <div class="row"> 
    <div class="col-md-6"> 
     <form class="form-inline"> 
      <input #distance class="form-control" placeholder="Distance"> 
      <button #femaleGender type="button" class="btn btn-default" [class.active]="(genderStream | async) === 1">Female</button> 
      <button #maleGender type="button" class="btn btn-default" [class.active]="(genderStream | async) === 0">Male</button> 
     </form> 
    </div> 
    <div class="col-md-6"> 
     <h4>Result: {{ resultStream | async }}</h4> 
    </div> 
    </div> 
`, 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class AppComponent implements AfterViewInit { 

    // Weird fix: I need to add .interval(?) for async pipe to work later on... 
    resultStream: Observable<string> = Observable.interval(1000).map(() => ""); 
    genderStream: Observable<number> = Observable.interval(1000); 

    @ViewChild('distance') distance: ElementRef; 
    @ViewChild('maleGender') maleGender: ElementRef; 
    @ViewChild('femaleGender') femaleGender: ElementRef; 


    ngAfterViewInit() { 
     let distance$ = Observable.fromEvent(this.distance.nativeElement, 'keyup') 
      .map((event: Event) => event.target) 
      .map((element: HTMLInputElement) => element.value) 
      .map(value => parseInt(value)) 
      .filter(value => !isNaN(value)); 

     // In the calculation 0 is used for males and 1 for females. 
     let male$ = Observable.fromEvent(this.maleGender.nativeElement, 'click').map(() => 0); 
     let female$ = Observable.fromEvent(this.femaleGender.nativeElement, 'click').map(() => 1); 
     let gender$ = Observable.merge(male$, female$); 

     this.genderStream = gender$; 

     this.resultStream = Observable.combineLatest(
      distance$, 
      gender$, 
      (distance, gender) => calculateResult(distance, gender).toFixed(1) 
     ); 
    } 
} 

const calculateResult = (distance: number, gender: number) => 18.38 + (0.033 * distance) - (5.92 * gender); 
+1

あなたのplunkrから関連コンテンツを取り出し、あなたの投稿に編集してください。リンクが最終的に期限切れになるため、同様の問題が発生している他のユーザーにとってあなたの投稿は多かれ少なかれ役に立たなくなります。加えて、基本的には、助けようとしている人に、その助けを提供するためにいくつかのフープをジャンプするように頼んでいます。 –

+0

完了。そして良い点! – skovmand

+0

私はそれがChangeDetectionStrategy.OnPushと関係していると思います。 – skovmand

答えて

1

私はそれを考え出しました。

親コンポーネントの変更検出がChangeDetectionStrategy.OnPushに設定されていたためです。コンポーネント内でそれを無効にし、親ページがトリックを行いました。

import { Component, ChangeDetectionStrategy } from '@angular/core' 

@Component({ 
    selector: 'parent-page', 
    // Disabling OnPush change detection did the trick: 
    // changeDetection: ChangeDetectionStrategy.OnPush, 
    templateUrl: './parent.html' 
}) 
export class ParentPage {} 
+0

OnPushを再度有効にすると良いでしょう。どうすればいい? – skovmand

+0

ngAfterViewInitをngAfterContentInitに変更すると、OnPushでも問題なく動作することがわかりました。 – skovmand

関連する問題