NgRx 12的concatLatestFrom搭配多selector结合Nx navigation报错如何解决
问题原因排查
concatLatestFrom本身完全支持传入多个Observable组成的数组,并非只能传递单个selector,你遇到的类型不兼容问题和NgRx的操作符无关,问题出在Nx提供的navigation操作符的类型定义上。
从报错信息可以明确看到,navigation操作符只接收长度为2的元组类型[Action, unknown]作为入参,而你用concatLatestFrom传入两个selector后,返回的元组长度为3(格式为[Action, Case[], boolean]),超出了navigation的类型限制,因此触发类型报错。
另外你原代码中concatLatestFrom里的selector顺序是先取getAllCases,再取getCasesLoaded,返回的元组后两位顺序是[cases, loaded],和你run方法里解构的[loaded, cases]顺序不匹配,调整写法的时候注意对应顺序,避免出现逻辑错误。
临时解决方案
你可以通过将多个selector的返回值合并为单个对象的方式,适配navigation的类型要求,有两种常用写法:
方案1:在concatLatestFrom内合并返回值
loadAllCases$ = createEffect(() => this._actions$.pipe( concatLatestFrom(() => combineLatest([ this.store.pipe(select(CaseSelectors.getCasesLoaded)), this.store.pipe(select(CaseSelectors.getAllCases)) ]).pipe( map(([loaded, cases]) => ({ loaded, cases })) ) ), navigation(this.caseLandingPage, { run: (snap, { loaded, cases }) => { if (loaded) { return CaseActions.loadAllSuccess(); } else { return this._caseService.getAll().pipe( map(cases => CaseActions.loadAllSuccess(cases)) ); } }, onError: (action, error) => { return CaseActions.loadAllFailed(error); } }) ));
方案2:在concatLatestFrom后新增map操作符转换格式
loadAllCases$ = createEffect(() => this._actions$.pipe( concatLatestFrom(() => [ this.store.pipe(select(CaseSelectors.getCasesLoaded)), this.store.pipe(select(CaseSelectors.getAllCases)) ]), map(([action, loaded, cases]) => [action, { loaded, cases }] as const), navigation(this.caseLandingPage, { run: (snap, { loaded, cases }) => { if (loaded) { return CaseActions.loadAllSuccess(); } else { return this._caseService.getAll().pipe( map(cases => CaseActions.loadAllSuccess(cases)) ); } }, onError: (action, error) => { return CaseActions.loadAllFailed(error); } }) ));
两种方案都可以绕开当前Nx的类型限制,等后续Nx修复该问题后,就可以恢复你原来的写法。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

