![](/img/trans.png)
[英]Angular 7 with NGRX - subscription to a store property through selector getting called multiple times
[英]Subscription called multiple times dialog is opening twice after mutation of state using Ngrx - Angular
對話框多次打開,因為在 ngrx 狀態突變后訂閱被調用兩次/多次。
嘗試使用 takeUntil(loadingComplete) 和 loadingComplete = new BehaviorSubject(false) 但不適用於我的邏輯。 因為至少應在作業狀態為“已完成”后調用此訂閱一次。
嘗試使用 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.