2

我在 Angular 6 中使用 ngrx / (store, effects)。我在解析器解析其中一个路由变量时遇到了问题。这里是代码和解释

解析器

@Injectable()
export class HkSpecialitiesResolver implements Resolve<Speciality[]> {

  constructor(
    private store: Store<AppState>) {
  }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Speciality[]> {
    return this.store
      .pipe(
        select(selectAllSpecialities),
        tap(specialities => {
          if (!specialities || specialities.length === 0) {
            this.store.dispatch(new AllSpecialitiesRequested());
          }
        }),
        filter((specialities: Speciality[]) => {
          return specialities !== [];
        }),
        take(select(selectAllSpecialities).length)
      );
  }
}

效果

@Injectable()
export class HkSpecialitiesEffects {

  @Effect()
  loadAllSpecilities$ = this.actions$
    .pipe(
      ofType<AllSpecialitiesRequested>(SpecialityActionTypes.AllSpecialitiesRequested),
      withLatestFrom(this.store.pipe(select(allSpecialitiesLoaded))),
      filter(([action, allSpecialitiesLoaded]) => {
        console.log('loadAllSpecilities$ - ', [action, allSpecialitiesLoaded]);
        return !allSpecialitiesLoaded;
      }),
      mergeMap((o) => {
        console.log('loadAllSpecilities$ - mergeMap', o);
        return this.specialityService.findAll();
      }),
      map((specialities: Speciality[]) => {
        console.log('loadAllCourses$ - map', specialities);
        return new AllSpecialitiesLoaded({specialities});
      })
    );

  constructor(private actions$: Actions, private specialityService: HkSpecialitiesService,
              private store: Store<AppState>) {

  }
}

减速器

export interface SpecialitiesState extends EntityState<Speciality> {
  allSpecialitiesLoaded: boolean;
}

export const adapter: EntityAdapter<Speciality> =
  createEntityAdapter<Speciality>({
    selectId: (speciality: Speciality)  =>  {
      return (speciality !== undefined) ? speciality.uuid : undefined;
    }
  });


export const initialSpecialitiesState: SpecialitiesState = adapter.getInitialState({
  allSpecialitiesLoaded: false
});


export function specialityReducer(state = initialSpecialitiesState, action: SpecialityActions): SpecialitiesState {
  switch (action.type) {
    case SpecialityActionTypes.SpecialityLoaded:
      return adapter.addOne(action.payload.speciality, state);
    case SpecialityActionTypes.AllSpecialitiesLoaded:
      return adapter.addAll(action.payload.specialities, {...state, allSpecialitiesLoaded: true});
    case SpecialityActionTypes.SpecialitySaved:
      return adapter.updateOne(action.payload.speciality, state);
    default: {
      return state;
    }
  }
}

export const {
  selectAll,
  selectEntities,
  selectIds,
  selectTotal

} = adapter.getSelectors();

服务

@Injectable()
export class HkSpecialitiesService {

  constructor(private http: HttpClient) {
  }

  findAll(): Observable<Speciality[]> {
    const vm = this;
    // it works with these lines
    /*return Observable.create((observer) => {
  observer.next([{id: 'a', uuid: 'a', name: 'Psychology', description: 'Psychology'}]);
});*/
    // Not works with this line
    return vm.http.get<Speciality[]>('/api/specialities').pipe(map((specialities) => specialities));
  }
}

问题是,就像代码一样,resolves specialties 变量被解析为空([]),在组件中我将其设为空,一个空数组。但是,如果在服务中,我更改了 http 调用,对于被注释的行,解析器中变量的解析采用我返回的唯一正确值。

“解析器”在效果结束之前被解析,当它在服务中调用 http 的获取时。

我不明白的是,注释行(一切正常)返回一个与 http 调用内容相同的 observable。

有什么建议么?

4

0 回答 0