如何以角度循环遍历异步数据

时间:2019-02-05 14:56:28

标签: angular ngfor

我有一个角度组件,可以从服务器上获取数据,然后在将其分配给变量之前对其进行转换:

class Component {
  data = [];

  ngOnInit() {
    this.store.select(data).pipe(
      map(data => { this.data = this.transformData(data); })
    ).subscribe();
  }

  transformData(data) {
    // data is an array of data
    return data.map(item => item);
  }
}

上面是我正在做的简化版本,transform方法做得更多,但无关紧要。

然后我尝试使用数据进行for循环,但它不会显示任何内容,也不会抛出任何错误:

<div *ngFor="let item of data|async">
  {{ item.prop1 }} {{ item.prop2 }}
</div>

我不确定为什么会发生这种情况-我习惯于在传递prop或更新状态并重新渲染组件时做出反应,角度上的工作流程是什么?

我尝试了this solution,但仍然无法显示任何数据:

class Component {
  data = [];

  ngOnInit() {
    this.store.select(data).pipe(
      map(data => { this.data = this.transformData(data); })
    ).subscribe();
  }

  transformData(data) {
    // data is an array of data
    // notice 'of()'
    return of(data.map(item => item));
  }
}

为澄清起见,我在console.log上确实看到this.data的值发生了变化,但是html并未呈现数据

4 个答案:

答案 0 :(得分:1)

要使用async,可以将ObservablePromise传递给*ngFor。因此,您需要将this.store.select的返回值分配给data,而不使用subscribe

class Component {
  data: Observable<any>;

  ngOnInit() {
    this.data = this.store.select(data).pipe(
      map(result => { return this.transformData(result); })
    );
  }

  transformData(data) {
    // data is an array of data
    return data.map(item => item);
  }
}

如果您不会在transformData方法中进行任何修改,则可以删除pipe

class Component {
      data: Observable<any>;

      ngOnInit() {
        this.data = this.store.select(data);
      }

 }

答案 1 :(得分:0)

不太确定您在transformData方法中正在做什么。实际上,您实际上返回的是相同的data

尽管尝试一下:

class Component {
  data$: Observable<any[]>;

  ngOnInit() {
    this.data$ = this.store.select(data).pipe(
      map(data => this.transformData(data))
    );
  }

  transformData(data) {
    return data.map(item => item);
  }
}

然后在您的模板中:

<div *ngFor="let item of data$ | async">
  {{ item.prop1 }} {{ item.prop2 }}
</div>

答案 2 :(得分:0)

如果您确定错误不在您的service内。

那么也许您可以尝试这样的事情:

class Component {
  private data = Observable<Array<any>>;

  public ngOnInit() {
    this.store.select(data).pipe(
      map(data => { this.data = this.transformData(data); })
    );
  }

  private transformData(data): Observable<any> {
    // data is an array of data
    // notice 'of()'
    return of(data.map(item => item));
  }
}

HTML:

<div *ngFor="let item of data | async">
    {{item.prop}}
</div>

由于我看不到您的服务,因此我将不得不承担 ...

我建议您在此处使用Promise,因为我发现它们在寻求异步的情况下更容易使用。另外,不要在这里传递管道,而要在您的服务中进行。这样,您只需要将原始数据吐出到HTML视图中,就不需要在控制器中进行任何转换,而且那样您就知道您有数据(因为您可以在更早的阶段从服务而不是控制器中获取数据) )。

答案 3 :(得分:0)

您可以这样使用。

class Component {
  data = [];

  ngOnInit() {
    this.store.select(data).pipe(
      map(data => this.transformData(data))
    ).subscribe(result=> { this.data =result});
  }

  transformData(data) {
    // data is an array of data
    return data.map(item => item);
  }
}