订阅一次 ngrx-data 服务调用会被调用两次

问题描述 投票:0回答:3

我对 ngrx-data 很陌生,我试图找出为什么加载一些记录需要这么长时间

这是我订阅 ngrx-data 实体的方式:

    this.subscriptions.push(this.mileageTrackingManagmentService.entities$.subscribe(data => {
      console.log('>>subscribe mileageTrackingManagmentService - ' + new Date());
      let tempDataset = data || [];
      this.calculateTotalMileageForMultipleDays(tempDataset);
      this.mileageTrackingManagment = tempDataset;
      this.filteredMileageTrackingManagement = this.mileageTrackingManagment;
      //this.setFilter();
      //this.cdRef.detectChanges();
    }));

这是我如何调用 ngrx-data 服务来发出 http 请求

  private loadMileageTracking() {
    if (this.domain) {
      console.log('loadMileageTracking');
      if (this.dateOption == DateOptions.Day && this.selectedResource) {
        this.mileageTrackingService.getTrackingByResourceIdAndDomainId(this.startDate, this.selectedResource.resourceId, this.domain.id);
      } else {
        console.log('getManagment');
        this.mileageTrackingManagmentService.getManagment(this.startDate, this.endDate, this.dateOption, this.domain.id)
      }
    }
  }

从我在控制台中看到的,订阅反应逻辑被 gettig 调用了两次,相差 15 秒。在网络选项卡中,我可以看到两个请求都成功并且包含数据。

我在显示数据的检测更改上做错了,这是标准行为吗?

我尝试过的事情

  • entities$.pipe(skip(1)).subscribe...
  • 实体$.pipe(take(1)).订阅...

没有按预期工作,因为仅显示给定的请求,而忽略任何其他请求

我不是在寻找一种方法来忽略请求返回的数据,我想要的是知道为什么 ngrx-data 或我的代码对单个调用 ngrx-data 服务执行两个 http 请求

服务的实现方式如下

export class MileageTrackingManagmentService extends EntityCollectionServiceBase<MileageTrackingManagment> {

    constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
        super('MileageTrackingManagment', serviceElementsFactory);
    }

    public getManagment(startDate: Moment, endDate: Moment, grouping: DateOptions, domainId?: string): Observable<MileageTrackingManagment[]> {
        this.clearCache();

        return this.getWithQuery(MileageCommon.buildQuery(startDate, endDate, grouping, domainId));
    }
}

我也检查过其他类似的问题,但运气不佳

angular ngrx angular-ngrx-data
3个回答
2
投票

如果您在应用程序范围内使用返回的数据执行的所有其他操作都按预期工作,并且您只需要在给定页面/上下文中一次数据,您可以尝试将

pipe(take(1))
添加到订阅 [with
import { take } from 'rxjs/operators';
],确保您只得到发出的第一个值。查看更多信息https://rxjs.dev/api/operators/take


1
投票

我相信这就是正在发生的事情:

entities$.subscribe(
entities$
当前值产生一次,然后每次
entities$
的值发生变化时产生一次。

订阅发生时(在这一行)

 ... (this.mileageTrackingManagmentService.entities$.subscribe(data => ...

当前

entities$
值为产量;

然后调用服务函数

loadMileageTracking

过了一段时间(每张图片 15 秒),FE 收到了数据;

这会导致与您的实体相关的商店中的数据发生更改,因此

...entities$.subscribe(data => ...
再次产生。

如果您需要订阅在后端处理服务的 http 请求时不产生收益,我建议您向存储添加一个属性以指示值是否正在加载。

让我称其为

loading
,并假设您有一个可观察的
loading$
为您服务,以便论证。然后你可以这样做:

this.mileageTrackingManagmentService.loading$.pipe(filter(loading => !loading),take(1)).subscribe(() => {
{
  this.subscriptions.push(this.mileageTrackingManagmentService.entities$.subscribe(data => {
    let tempDataset = data || [];
    this.calculateTotalMileageForMultipleDays(tempDataset);
    this.mileageTrackingManagment = tempDataset;
    this.filteredMileageTrackingManagement = this.mileageTrackingManagment;
  }));
});

在此示例中,您还需要将

loading
属性值的处理添加到您的化简器中。该操作将其值设置为
true
,并且与成功和失败相关的操作都将其设置为
false


0
投票

我也遇到同样的问题了!这是因为我在根组件中订阅了EntityEffects!希望能解决。

© www.soinside.com 2019 - 2024. All rights reserved.