【问题标题】:Subscribe to service making multiple parallel requests for each item in a list订阅对列表中的每个项目发出多个并行请求的服务
【发布时间】:2018-01-30 03:36:10
【问题描述】:

我在 Angular 5 中有一个显示项目列表的组件。 这些项目是通过调用服务并订阅它来填充的。 该服务需要首先发出请求以获取项目列表,该列表返回“事件”列表。一个新的列表 myItems 是根据这个响应构建的。 然后,对于每个项目,都会发出一个新请求以获取项目的描述,并使用结果更新项目。 数据似乎已正确构建,并且似乎调用了订阅回调,但我的组件模板没有显示任何内容。 我相信我在服务中做错了什么(可能是 flatMap)。

组件:

ngOnInit() {
    this.itemsService.getItems()
        .subscribe((items: Item[]) => {
            // console.log(items) here seems fine, but the template does not display anything
            this.items = items;
        });
}

组件模板:

<ul *ngFor="let item of items">
    <li>{{item.description}}</li>
 </ul>

服务:

public getItems(): Observable<Item[]> {
    let myItems = [];

    return this.httpService.get('items')
        .map((response: any) => {
            if (response.events) {
                let eventObj: Item;
                for (let i = 0; i < response.events.length; i++) {
                    if (response.events[i]) {
                        eventObj = new Item(response.events[i]);
                        myItems.push(eventObj);
                    }
                }
            }
            return myItems;
        })
        .flatMap((items: Item[]) => {
            const itemsObservables = items
                .map((item: Item) => {
                    return this.itemService.getDescription(item.id)
                        .map((response) => {
                            item.description = response;
                            return item;
                        });
                });
            return Observable.forkJoin(itemsObservables)
                .map(data => {
                    return myItems;
                });
        });
}

【问题讨论】:

  • 你应该避免填充 observable 状态并在 observable 之外跟踪它。这是一种反模式。
  • 谢谢@pixelbits,你能澄清一下我应该改变什么来避免反模式吗?

标签: angular rxjs


【解决方案1】:

如果没有必要,请避免跟踪可观察状态。假设您有这样做的正当理由,我相信您可以通过更改最后一条语句以使用传播运算符来解决您的直接问题:

return Observable.forkJoin(...itemsObservables); 

【讨论】:

    【解决方案2】:

    您的模板可能会由于这些类型的异步操作中预期的延迟而崩溃。请将访问/显示此数据的所有节点的模板中的语法更改为如下所示:

    <li>{{item?.description}}</li>
    

    事实上,在你让它工作之前,将问号添加到模板中的所有访问器。一旦你得到一些工作,你可以根据需要将它们拉回来。

    &lt;li&gt;{{item?.entity?.name?.firstname}}&lt;/li&gt;

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2018-10-21
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 2015-06-26
      • 1970-01-01
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      相关资源
      最近更新 更多