Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
子组件的Angular2异步问题_Angular_Typescript - Fatal编程技术网

子组件的Angular2异步问题

子组件的Angular2异步问题,angular,typescript,Angular,Typescript,我有一个从数据库加载数据的父组件。这些数据来自我的服务,它返回一个承诺 组件: ngOnInit() { this._massEmpService.fetchFilterFields() .then(results => { this.fields = { areas: results['areas']['options'], silos: results['silos']['o

我有一个从数据库加载数据的父组件。这些数据来自我的服务,它返回一个承诺

组件:

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));
    });
};
@Input() fields: any;

ngAfterViewInit() {
    console.log(this.fields); // No data
}
<app-import [fields]="fields"></app-import>
我试图将我的
this.fields
数据传递给子组件,但当我尝试使用子组件中的数据时,它似乎无法访问它

子组件:

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));
    });
};
@Input() fields: any;

ngAfterViewInit() {
    console.log(this.fields); // No data
}
<app-import [fields]="fields"></app-import>
父HTML:

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));
    });
};
@Input() fields: any;

ngAfterViewInit() {
    console.log(this.fields); // No data
}
<app-import [fields]="fields"></app-import>


我认为这是一个异步问题,但我认为使用
afterViewInit
可能已经解决了这个问题。有什么想法吗?

使用
ngOnChanges()
,每次输入属性的值发生变化时都会调用它。

我的建议是使用带有
主题的共享服务和
可观察的
,这样子组件变量就可以
订阅数据流

通过数据绑定方式,子组件加载父组件,因此当
Promise
返回数据时,子组件不知道它,因此需要重新初始化以获取数据
Observable
subscription
消除了该问题

我创建了一个将promise数据返回给子组件(额外增加了2000ms的延迟)的组件。如果它适合您,您可以在代码中轻松实现它:)

parent.component.ts:

constructor(private appState: AppState){ }

  ngOnInit(){
    this.getData();
  }

  getData(): void {
    this.appState
        .fetchFilterFields()
        .then(data => {
          // console.log(data)
          this.appState.setData(data);
        });
} 
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; 
      });

}
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);
  }