Angular中如何在CanDeactivateFn守卫内发起异步请求?
解决Angular CanDeactivateFn守卫的异步弹窗返回问题
你的问题出在异步结果的处理方式错误:使用subscribe时,回调内部的return不会作为守卫函数的返回值,且await的是Subscription对象而非Promise,导致守卫函数在存在未保存数据时没有返回值,触发类型错误和路径未返回值警告。
修复方案
利用RxJS的firstValueFrom将弹窗的Observable转为Promise,正确获取异步结果并返回:
- 先导入
firstValueFrom:
import { firstValueFrom } from 'rxjs';
- 修改守卫函数:
export const unsavedDataGuard: CanDeactivateFn<boolean> = async () => { const utService = inject(UTService); const alertService = inject(AlertService); const unsaved = utService.unsaved; if (unsaved) { // 将弹窗关闭后的Observable转为Promise,获取用户选择结果 const result = await firstValueFrom(alertService.openQuestion('Cancel?').afterClosed()); // 确保返回布尔值(处理弹窗返回null/undefined的情况) return !!result; } // 无未保存数据时直接允许离开 return true; };
关键说明
firstValueFrom会把afterClosed()返回的Observable转换为Promise,当弹窗关闭发射结果后,Promise会resolve该值,完美适配异步场景。- 原生
confirm是同步API,直接返回布尔值自然符合守卫要求,但自定义弹窗是异步Observable,必须转Promise才能让async函数正确返回结果。 !!result用于将null/undefined等非布尔值转为标准布尔值,避免类型异常。
内容的提问来源于stack exchange,提问作者Rui
相关产品推荐
相关产品推荐

