Angular中Ngrx与Resolver配合时take(1)无法获取新值问题求解
问题修复方案
1. 配置路由触发Resolver重新运行
Angular默认情况下,同一个路由路径仅参数变化时,不会重新执行守卫和解析器,需要在对应路由的配置中新增runGuardsAndResolvers属性:
// 路由定义文件 const routes: Routes = [ { path: 'account/:accountId', component: AccountDetailComponent, resolve: { account: AccountResolver }, // 参数变化时重新运行Resolver runGuardsAndResolvers: 'paramsOrQueryParamsChange' } ];
2. 优化Resolver代码逻辑
调整原有代码的流结构,合并监听账户数据和错误状态,同时避免历史错误状态干扰本次请求:
resolve(route: ActivatedRouteSnapshot): Observable<Account | null> { const id = this.getParameter(route, 'accountId'); if (!id) return null; // 先清空之前的账户错误状态,避免历史错误干扰 this._store.dispatch(AccountsPageActions.clearAccountError()); // 触发当前id的账户数据加载 this._store.dispatch(AccountsPageActions.loadAccountWithDetails({ accountId: id })); // 同时监听当前id的账户数据和全局账户错误状态 return combineLatest([ this._store.select(getAccountDetailById(id)), this._store.select(getAccountError) ]).pipe( // 处理加载错误 tap(([_, error]) => { if (error instanceof HttpErrorResponse && error.message.includes(id)) { this._utilService.showErrorToast('Zugang nicht gefunden'); this._router.navigateByUrl('/'); } }), // 过滤出符合当前id的有效账户数据 filter(([account, error]) => !error && !!account && account.id === id), // 取第一个符合条件的值后结束流,避免内存泄漏 take(1), // 仅返回账户数据作为Resolver的解析结果 map(([account]) => account) ); }
额外说明
- 原有代码中的
take(1)本身逻辑没有问题,它的作用是在拿到符合要求的数据后立即结束当前流,不会影响后续参数变化后新生成的流的取值。 - 如果你没有定义清空账户错误的Action,可以新增一个对应Action,或者在错误处理逻辑后增加清空错误的dispatch操作,避免错误状态长期留存。
内容的提问来源于stack exchange,提问作者MarcelSauter
相关产品推荐
相关产品推荐

