2017-07-20 15 views
1

データベースからデータをロードする親コンポーネントがあります。このデータは、約束を返す私のサービスから来ています。Angular2子コンポーネントの非同期問題

コンポーネント:

ngOnInit() { 
    this._massEmpService.fetchFilterFields() 
     .then(results => { 
      this.fields = { 
       areas: results['areas']['options'], 
       silos: results['silos']['options'], 
       departments: results['departments']['options'], 
       locations: results['locations']['options'], 
       segments: results['segments']['options'], 
       roles: results['roles']['options'] 
      }; 
     }); 
} 

サービス:

fetchFilterFields() { 
    return new Promise((resolve, reject) => { 
     this._http.get(this.baseUrl + '/fetchImportFields', { "headers": this.headers }) 
      .map((result: Response) => result.json()) 
      .subscribe((results) => resolve(results.data)); 
    }); 
}; 

私は子コンポーネントに私のthis.fieldsデータを渡すためにしようとしていますが、私は試してみて、子コンポーネントにデータを使用するときそれにアクセスすることはできません。

子コンポーネント:

@Input() fields: any; 

ngAfterViewInit() { 
    console.log(this.fields); // No data 
} 

親HTML:

<app-import [fields]="fields"></app-import> 

は、私は、これは非同期の問題であると考えているが、私はafterViewInitを使用して思ったが、それを解決している可能性があります。何かご意見は?

答えて

1

SubjectObservableの共有サービスを使用して、子コンポーネント変数がデータストリームに対してsubscribeになるようにすることをお勧めします。

データバインディングの方法では、子コンポーネントに親がロードされるため、Promiseがデータを返すと、子コンポーネントはそれを認識しないため、データを取得するために再初期化する必要があります。 Observableおよびsubscriptionはこの問題を解決します。

これは、子コンポーネントに約束データを返すPlunker demoを作成しました(余分な遅延が2000ms追加されています)。

constructor(private appState: AppState){ } 

    ngOnInit(){ 
    this.getData(); 
    } 

    getData(): void { 
    this.appState 
     .fetchFilterFields() 
     .then(data => { 
      // console.log(data) 
      this.appState.setData(data); 
     }); 
} 

service.ts:

private headers = new Headers({'Content-Type': 'application/json'}); 
    private apiUrl = 'api/data'; 

    // Observable string source 
    private dataStringSource = new Subject<string>(); 

    // Observable string stream 
    dataString$ = this.dataStringSource.asObservable(); 

    constructor(private http: Http) { } 

    public setData(value) { 
    this.dataStringSource.next(value); 
    } 

    fetchFilterFields() { 
    console.log(this.apiUrl); 
    return this.http.get(this.apiUrl) 
       .delay(2000) 
       .toPromise() 
       .then(response => response.json().data) 
       .catch(this.handleError); 
    } 

    private handleError(error: any): Promise<any> { 
    console.error('An error occurred', error); // for demo purposes only 
    return Promise.reject(error.message || error); 
    } 

child.component.tsそれはあなたのために働く場合は、簡単にあなたのコード:)

parent.component.tsでそれを実装することができます:

fields: any; 

constructor(private appState: AppState){ 
    // this.mylist = this.appState.get('mylist'); 

    this.appState.dataString$.subscribe(
     data => { 
     // console.log("Subs to child" + data); 
     this.fields = data; 
     }); 

} 
0

ngOnChanges()を使用します。これは、入力プロパティの値が変更されるたびに呼び出されます。

関連する問題