簡體   English   中英

使用 Ngrx - Angular 改變狀態后,多次調用對話框的訂閱打開兩次

[英]Subscription called multiple times dialog is opening twice after mutation of state using Ngrx - Angular

對話框多次打開,因為在 ngrx 狀態突變后訂閱被調用兩次/多次。

  1. 嘗試使用 takeUntil(loadingComplete) 和 loadingComplete = new BehaviorSubject(false) 但不適用於我的邏輯。 因為至少應在作業狀態為“已完成”后調用此訂閱一次。

  2. 嘗試使用 take(1),因為我在使用 take 1 的第一次訂閱后無法獲取進度狀態的輪詢。因此添加 isCompleteDialogOpened 標志來控制多個訂閱對話框打開一次。 但是每次訂閱被調用時isCompleteDialogOpened 仍然是 !false

     if(uploadStatus.jobStatus === 'COMPLETED' && !this.isCompleteDialogOpened)

即使我在 openUploadCompleteDialog() 方法調用中的第一次訂閱時將其設置為 true 后,第二次訂閱時 isCompleteDialogOpened 為 false,因此對話框被多次打開。

 isCompleteDialogOpened = false;   // -->Init as false

 ngOnInit() {
            this.pollUploadStatus(); // --> Oninit call for subscription method
        }

 pollUploadStatus() { // --> uploadStore ngrx store when selectCurrentJob mutates this is subscribed
        this.uploadStore.select(selectCurrentJob)
            .pipe(filter(uploadJob => !!uploadJob && !!uploadJob.jobStatus))
            .subscribe((uploadJob) => { // --> Subscription called multiple times
                const uploadStatus = uploadJob.jobStatus;


                  // --> this.isCompleteDialogOpened remains false even if i set true when
                  // --> the dialog is opened on first subscription How to maintain the state 
                  // --> of 'isCompleteDialogOpened'  on each subscription so that when the second
                 // -->  subscription made it is set true and condition fails


                if (uploadStatus.jobStatus === 'COMPLETED' && !this.isCompleteDialogOpened) {
                    this.openUploadCompleteDialog(); // --> upload dialog box is called twice
                }             
    }


openUploadCompleteDialog(): void {

    this.isCompleteDialogOpened = true; // --> set true after dialog open on subscription

    const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
        data: ....
    });
    dialogRef.afterClosed().subscribe(result => {
        const message = this.translate
            .instant('upload-success');
        this.openUploadSnackBar(true, message);
        this.router.navigateByUrl('car/add-update/car-history');
    });
}

 ngOnDestroy() {
        this.uploadStore.dispatch(stopPolling({}));
        this.destroy$.next();
        this.destroy$.complete();
    }

可能與如何在對服務/商店的響應具有特定參數/值后停止訂閱的重復,但 takeUntil 不適用於我的邏輯

在狀態更改為“已完成”后,是否有任何方法可以根據標志將對話框打開一次,如果是標志如何在每個訂閱或其他內容上維護狀態。 任何幫助都會很棒。

使用 Angular8,Rxjs 6.5.2。

不知道為什么經常select火災,但在這里

 pollUploadStatus() { // --> uploadStore ngrx store when selectCurrentJob mutates this is subscribed
        this.uploadStore.select(selectCurrentJob)
            .pipe(filter(uploadJob => !!uploadJob && !!uploadJob.jobStatus))

filter之后,將distinctUntilChanged (可能使用自定義匹配器,因為流包含對象,而不是基元)添加到管道中,應該可以解決問題。

僅供參考:當我導航到其他一些選項卡返回時,此訂閱仍未訂閱,這就是問題所在。 DistinctUntilChanged 通過打印日志和刪除這些標志幫助我找到了主要問題,並使我的代碼變得干凈

private destroy$ = new Subject<void>();

pollUploadStatus() {
    this.uploadStore.select(selectCurrentJob)
        .pipe(filter(uploadJob => !!uploadJob && !!uploadJob.jobStatus),
        distinctUntilChanged((prev, curr) =>
            prev.jobStatus.percentComplete === curr.jobStatus.percentComplete),
            takeUntil(this.destroy$))
        .subscribe((uploadJob) => {
            const uploadStatus = uploadJob.jobStatus;
            if (uploadStatus.jobStatus === 'COMPLETED') {
                this.openUploadCompleteDialog(); --> this.router.navigateByUrl('car/add-update/car-history');
            }
        });
}

ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM