如何让CanDeactivate与Kendo UI Angular对话框协同工作?
解决Kendo UI Angular对话框在CanDeactivate路由守卫中的异步问题
你的核心问题在于同步返回值和异步对话框的时序冲突:原代码里return this._canExitResult$$.value会在用户点击对话框按钮前执行,拿到的是Subject初始值false;第二次导航时Subject里存的是上次的选择结果,所以才会“看似正确”。
要彻底解决这个问题,需要利用CanDeactivate守卫支持返回Observable<boolean>的特性,让守卫等待用户的对话框选择结果,而不是同步返回值。
修正后的代码
首先修改组件的canExit方法,支持返回布尔值或Observable:
import { Observable, of } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; // ... public canExit(): Observable<boolean> | boolean { // 表单未修改时直接允许导航 return this.form.dirty ? this.confirmCanExitDialog() : true; } private confirmCanExitDialog(): Observable<boolean> { const dialogRef = this.dialogService.open({ content: ConfirmDialogComponent, }); const confirmDialog = dialogRef.content.instance as ConfirmDialogComponent; confirmDialog.message = 'Confirmation.CanExit'; // 直接将对话框结果映射为布尔值Observable,交给守卫等待 return dialogRef.result.pipe( // 根据对话框返回结果判断是否允许退出 map((result: DialogCloseResult) => result === 'Yes'), // 处理用户点击对话框外部、按ESC关闭等意外情况,默认阻止导航 catchError(() => of(false)) ); }
关键说明
- 移除Subject中转:不需要用
_canExitResult$$来存储结果,直接利用dialogRef.result这个Observable,守卫会自动订阅并等待它发出值。 - 异步等待逻辑:CanDeactivate守卫会识别返回的Observable,暂停导航流程直到Observable发出结果,这样就能准确获取用户的选择。
- 异常处理:添加
catchError处理对话框意外关闭的场景,避免守卫因Observable报错而中断。
内容的提问来源于stack exchange,提问作者ZotNet
相关产品推荐
相关产品推荐

