如何避免两次调用观察方法?

时间:2020-08-17 08:48:54

标签: angular

API调用在ngOnInit上实现,如下所示:

ngOnInit() {
    this.applicationObs = this.route.paramMap.pipe(
        filter((params) => params.has('id')),
        switchMap((params) => this.applicationService.getApplicationDetails(params.get('id'))),
        map((data: ApplicationResponse) => data),
    );

    this.applicationObsSubscription = this.applicationObs.subscribe((response) => {
        const fabricaSidebar = fabricApplicationSidebarMenu(response.application);
        this.sidebarSections = fabricaSidebar.getSidebarMenuItems();
    });
}

然后在模板中,我使用async来获取数据:

<ng-container *ngIf="applicationObs | async as app; else loading">

问题是它调用两次,一次调用async,另一次调用subscribe

如何解决此问题?

2 个答案:

答案 0 :(得分:1)

您可以尝试使用其他变量

applicationObs$ = new BehaviorSubject(null);

ngOnInit() {
    this.applicationObs = this.route.paramMap.pipe(
        filter((params) => params.has('id')),
        switchMap((params) => this.applicationService.getApplicationDetails(params.get('id'))),
        tap((data: ApplicationResponse) => this.applicationObs$.next(data)),
    )
    .subscribe((response) => {
        const fabricaSidebar = fabricApplicationSidebarMenu(response.application);
        this.sidebarSections = fabricaSidebar.getSidebarMenuItems();
    })
}

<ng-container *ngIf="applicationObs$ | async as app; else loading">

答案 1 :(得分:1)

有多种解决方法。看到操作符链的末尾有一个map,可以在其中分配sidebarSections而不是单独的订阅。尝试以下

ngOnInit() {
  this.applicationObs = this.route.paramMap.pipe(
    filter((params) => params.has('id')),
    switchMap((params) => this.applicationService.getApplicationDetails(params.get('id'))),
    map((data: ApplicationResponse) => {
      this.sidebarSections = this.fabricApplicationSidebarMenu(data.application).getSidebarMenuItems();
      return data;
    })
  );
}

如果您没有从map返回转换后的变量,则也可以使用tap运算符来代替return语句。

因此,记住只有渲染具有async管道的相关DOM元素时才触发订阅(并分配变量),这一点也很重要。