首页 > 解决方案 > ngFor 中的 AsyncPipe 用于项目

问题描述

如何使用AsyncPipe inside anngFor或最佳实践来完成对列表项的异步调用?

示例: 假设我有一个产品订单,我想显示产品的制造商。但是制造商需要从存储(本地存储)中加载才能显示。我最初的解决方案如下(未经测试的伪代码):

HTML:

<ol>
  <li *ngFor="let prod of order.toProducts">
    {{ prod.Name }}: {{ DisplayManufacturer(prod) | async }}
  </li>
<ol>

打字稿:

public async DisplayManufacturer(prod: product) {
    let manufacturer = await this.storageService.Load(prod.manufacturerId);
    if (manufacturer) {
        return manufacturer.name + ' (' + manufacturer.address + ')';
    }
    return "";
}

这 - 当然 - 导致无限循环。

我的下一个解决方案是,遍历所有订单及其里面的所有产品ngOnInit以找到制造商并将它们存储在 a 中以Map供以后在表达式中使用。

我觉得应该有一个更好的解决方案 - 因为这还没有结束:我还必须实施DoCheck以检查是否有任何产品阵列或制造商发生变化并重新加载所述地图。这适用于每个类似引用的字段。

标签: angular

解决方案


您不需要在显示之前使用 async/await 或加载所有数据。向product类型添加一个字段并分配一个 Promise 或一个 Observable 来解析所需的数据。

服务

Load(id: any): any {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(`Manufacturer id [${id}], name, address`);
        }, Math.random() * 5000 + 2000);
    });
}

零件

ngOnInit() {
    for (let i = 1; i < 10; i++) {
        this.order.toProducts.push(
            { Name: 'ProdName' + i, manufacturerId: i, data: this.storageService.Load('manufacturerId#' + i) },
        );
    }
}

模板

<ol>
  <li *ngFor="let prod of order.toProducts">
    {{ prod.Name }}: {{ prod.data | async }}
  </li>
<ol>

完整的工作示例:https ://stackblitz.com/edit/angular-gpqvuu


推荐阅读