我有以下代码
this.subscription = this.someService.subscribe((event: FormEvent) => {
let isConfirmed:boolean;
this.openDialog();
const confirmDialogSubscription:Subscription =
this.dialogRef.componentInstance.onConfirm.subscribe(() => {
this.dialogRef.close();
isConfirmed = true;
});
const closeDialogSubscription =
this.dialogRef.componentInstance.onClose.subscribe(() => {
this.dialogRef.close();
isConfirmed = false;
});
//Should be executed after one of these Subscription has fired
if(isConfirmed){
//keep on executing
}
else{
//stopEvent
event.preventDefault();
}
}
});
目前,我有一个典型的异步问题,即代码不断执行并处理事件。我要等待订阅。
(注意:我正在使用Angular Material对话框并定义了两个Output Event Emitters)
编辑:我的主要问题是,这个“ someService”是我正在使用的库的服务。它为我提供了订阅事件的可能性,但是一旦被触发,它也将成为现实。因此,在我的订阅结束之前,我需要是否调用event.preventDefault()
。
答案 0 :(得分:0)
将表达式移动到单独的函数中,并在订阅中调用
Menu1.Controls(i).OnAction = "'SheetChange """ & ws.Name & """'"
答案 1 :(得分:0)
最好将其转变成Observable链-避免在多个地方订阅,只订阅一次整个链:
let evt: FormEvent = null;
this.subscription = this.someService.pipe(
flatMap((event:FormEvent) => {
evt = event;
this.openDialog();
// Race will emit whichever of the passed observables emits first:
return race(
this.dialogRef.componentInstance.onConfirm.pipe(map(() => true)),
this.dialogRef.componentInstance.onClose.pipe(map(() => false))
);
})
).subscribe((confirmed) => {
if (!confirmed) {
return evt.preventDefault();
} else {
// Call whatever code you wish to continue if confirmed.
}
});
对于Observables,很少需要为单个逻辑流进行多个订阅-而是总是试图组成一个单个Observable来代表整个功能流,然后订阅一次。
关于异步性问题,请在下面的代码中内联查看我的注释-订阅将始终在您评估是否调用preventDefault的位置触发,并且如果someService中的事件在未阻止的情况下进行处理,相同的堆栈框架,将无法避免:
this.subscription = this.someService.subscribe((event: FormEvent) => {
let isConfirmed:boolean;
this.openDialog();
const confirmDialogSubscription:Subscription =
this.dialogRef.componentInstance.onConfirm.subscribe(() => {
///// THIS WILL EXECUTE ASYNCHRONOUSLY, SOME TIME LATER
this.dialogRef.close();
isConfirmed = true;
});
const closeDialogSubscription =
this.dialogRef.componentInstance.onClose.subscribe(() => {
///// THIS WILL EXECUTE ASYNCHRONOUSLY, SOME TIME LATER
this.dialogRef.close();
isConfirmed = false;
});
///// THIS WILL ALWAYS BE EXECUTED BEFORE EITHER OF THE ABOVE
///// SUBSCRIPTIONS SO isConfirmed WILL ALWAYS HAVE ITS DEFAULT
///// VALUE:
//Should be executed after one of these Subscription has fired
if(isConfirmed){
//keep on executing
}
else{
//stopEvent
event.preventDefault();
}
}
});
唯一的解决方案是使用一个不同的按钮来触发事件,然后,如果用户确认,则手动触发您要控制的事件(如果可能)。