Rxjs 在路由解析器中使用NGRX

Rxjs 在路由解析器中使用NGRX,rxjs,angular6,ngrx,Rxjs,Angular6,Ngrx,我用的是角度6。 我也在使用NGRX商店。 我正在使用route guard来确保用户已登录到应用程序。 然后,我使用解析器获取初始用户配置文件,然后将其放入NGRX存储中 我是NGRX新手,我不确定这是否是编写解析器的正确方法 resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any { return this.loginService.getLoginData() .pipe(

我用的是角度6。 我也在使用NGRX商店。 我正在使用route guard来确保用户已登录到应用程序。 然后,我使用解析器获取初始用户配置文件,然后将其放入NGRX存储中

我是NGRX新手,我不确定这是否是编写解析器的正确方法

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
     return this.loginService.getLoginData()
        .pipe(
            map((result:UserData) => { 
                this.store.dispatch(new userActions.SetLoginData(result)); 
                this.loginService.getDropdownData(
                    result.userId, 
                    result.countryCode,
                ).subscribe( data => { 
                    this.store.dispatch(new userActions.SetDropdownData(data));
                })
            })
        )
}  
我也不确定这是否是做RXJS的正确方法

任何建议, 谢谢

我要给大家指出,托德格言的一篇文章对此做了很好的解释

这里也有一个例子,警卫在

@Injectable()
导出类CoursesGuard实现CanActivate{
构造函数(私有存储:存储){}
getFromStoreOrAPI():可观察{
把这个还给我
.选择(GetCourseState)
.do((数据:任意)=>{
如果(!data.courses.length){
this.store.dispatch(new Courses.CoursesGet());
}
})
.filter((数据:任意)=>data.courses.length)
.采取(1)项措施;
}
canActivate():可观察的{
返回此文件。getFromStoreOrAPI()
.switchMap(()=>of(true))
.catch(()=>of(false));
}
}

首先,我认为将身份验证检查和数据解析分为不同的类是有意义的。对于身份验证,使用
CanActivate
guard更有意义。见:

这样,您的解析器就可以专注于只获取实际需要的数据。在这里,您需要意识到,如果您在解析器中返回一个可观察对象,则需要完成该可观察对象才能使解析器完成。问题是,如果您从存储中选择了某个内容,则生成的可观察内容将永远不会完成,因此您的解析器将永远不会完成数据解析。您可以使用
first()
take(1)
操作符来解决这个问题。timdeschryvers answer就如何实现这一点提供了一个很好的例子

@Injectable()
export class CoursesGuard implements CanActivate {
  constructor(private store: Store<CoursesState>) {}

  getFromStoreOrAPI(): Observable<any> {
    return this.store
      .select(getCoursesState)
      .do((data: any) => {
        if (!data.courses.length) {
          this.store.dispatch(new Courses.CoursesGet());
        }
      })
      .filter((data: any) => data.courses.length)
      .take(1);
  }

  canActivate(): Observable<boolean> {
    return this.getFromStoreOrAPI()
      .switchMap(() => of(true))
      .catch(() => of(false));
  }
}