首页 > 解决方案 > Angular/NgRx - 效果:Angular 扩展面板关闭时取消订阅和轮询

问题描述

我有一个列表,每个项目/作业都显示在一个有角度的材料扩展器面板中。

当用户打开其中一个扩展器时,我会调用 API 并获取要显示在扩展器主体中的信息。还有一个池化机制,每分钟刷新一次 API 中的数据。

我需要开始订阅,进行 http-call 并开始轮询,仅适用于打开的扩展器并在用户关闭任何扩展器时取消订阅并停止轮询

在组件 - 角材料扩展器面板中:

ngOnChanges() {
    if (this.panelOpenState === true) {
      this.currentStatus$ = this.store.pipe(select(fromJobs.getcurrentRunStatus(this.jobIDSelected)));   
    }
    if (this.panelOpenState === false) {
      this.store.dispatch(new Cancel_Refresh_Execution_Statuses(this.jobIDSelected));
    }
  }

我的问题在于,当添加参数以仅针对 JOB_ID 发送操作时,当扩展面板为此项目/作业关闭时,它给我一个错误:'无法调用类型缺少调用签名的表达式。类型“字符串”没有兼容的调用签名。

这是我的取消操作:

export class Cancel_Refresh_Execution_Statuses implements Action {
  readonly type = JobsActionType.CANCEL_REFRESH_EXECUTION_STATUSES;
  constructor(public jobId: string) {}
}
  @Effect()
  refreshCurrentExecutedJobStatuses$: Observable<Action> = this.actions$.pipe(
    ofType<jobActions.LoadJobStatusExecuted>(jobActions.JobsActionType.LOAD_JOB_STATUS_EXECUTED),
    mergeMap(
      (actions: jobActions.LoadJobStatusExecuted) =>
        timer(1000, 60000).pipe(
          concatMap(() =>
            from(
              this.jobsService.fetchJobsRunningStatus$(actions.param).pipe(
                takeUntil(
                  this.actions$.pipe(
                    ofType<jobActions.Cancel_Refresh_Execution_Statuses>(
                      //GETTING AN ERROR HERE: I CAN'T ADD A PARAM WITH THE JOB_ID 
                      //THAT I NEED TO CANCEL THE POLLING AND SUBSCRIPTION
                      jobActions.JobsActionType.CANCEL_REFRESH_EXECUTION_STATUSES(actions.param)
                    )
                  )
                ),
                map((lastRefreshStatus: Status) => new jobActions.JobsStatusExecutedSuccess(lastRefreshStatus)),
                catchError(err => of(new jobActions.JobsStatusExecutedFail(err)))
              )
            )
          )
        ) //end timer
    )
  );

非常感谢!

标签: angularngrxpollingeffect

解决方案


一个可行的解决方案是在显示视图的组件中设置轮询和订阅/取消订阅:

ngOnInit() {
  this.store.dispatch(new refreshJobLastStatus(this.jobId));
  this.currentStatus$ = this.store.pipe(select(fromJobs.refreshLastStatus(this.jobId)));
}

ngOnChanges() {
  if (this.panelOpenState) { 
    this.currentStatus$ = this.store.pipe(select(fromJobs.refreshLastStatus(this.jobId)));//here
    const timerRefreshJobStatuses = this.runtimeConfig.appConfig.jobsPollingRefreshStatus || 60000;
    this.statusesSub = timer(1000, timerRefreshJobStatuses).subscribe(() =>
      this.store.dispatch(new refreshJobLastStatus(this.jobId))
    );
     this.currentStatus$ = this.store.pipe(select(fromJobs.refreshLastStatus(this.jobId)));//?
  if (this.panelOpenState !== true) {
    if (this.statusesSub) {
      this.statusesSub.unsubscribe();
    }
  } 
}


推荐阅读