小编典典

如何使用 Angular 路由器防护装置附加 ngrx/store

all

我是 ngrx/store 的初学者,这是我第一个使用它的项目。

我已经成功地使用 ngrx/store 设置了我的 Angular 项目,并且在初始化我的主要组件后,我能够调度加载操作,如下所示:

ngOnInit() { this.store.dispatch({type: LOAD_STATISTICS}); }

我已经设置了一个效果来在分派此操作时加载数据:

@Effect()
loadStatistic = this.actions.ofType(LOAD_STATISTICS).switchMap(() => {
    return this.myService.loadStatistics().map(response => {
        return {type: NEW_STATISTICS, payload: response};
    });
});

我的减速器看起来像这样:

reduce(oldstate: Statistics = initialStatistics, action: Action): Statistic {
    switch (action.type) {
        case LOAD_STATISTICS:
            return oldstate;
        case NEW_STATISTICS:
            const newstate = new Statistics(action.payload);

            return newstate;
    ....

虽然这可行,但我无法理解如何将它与路由器防护一起使用,因为我目前只需要调度 LOAD_ACTION 一次。

此外,一个组件必须调度一个 LOAD 动作来加载初始数据对我来说听起来不正确。我希望商店本身知道它需要加载数据,而我不必先调度动作。如果是这种情况,我可以删除组件中的 ngOnInit() 方法。

我已经研究了 ngrx-example-app 但我还没有真正理解它是如何工作的。

编辑:

添加返回 ngrx-store observable 的解析保护后,路由不会被激活。这是解决方法:

   @Injectable()
  export class StatisticsResolver implements Resolve<Statistic> {
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Statistic> {
        // return Observable.of(new Statistic());
        return this.store.select("statistic").map(statistic => {
        console.log("stats", statistic);

        return statistic;
    });
}

这是路线:

const routes: Routes = [
    {path: '', component: TelefonanlageComponent, resolve: {statistic:  TelefonieStatisticResolver}},
];

阅读 107

收藏
2022-03-08

共1个答案

小编典典

在 AngularFrance 提供宝贵意见后,我自己解决了这个问题。由于我仍然是初学者,我不知道这是否应该这样做,但它确实有效。

我实现了这样的 CanActivate Guard:

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

    waitForDataToLoad(): Observable<Statistic> {
        return this.store.select(state => state.statistic)
            .filter(statistic => statistic && !statistic.empty);
    }

    canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
        this.store.dispatch({type: LOAD_STATISTIC});

        return this.waitForDataToLoad()
            .switchMap(() => {
                return Observable.of(true);
            });
        }
    }
}

canActivate(…) 方法首先调度一个动作来加载数据。在 waitForDataToLoad() 中,我们过滤数据已经存在并且不为空(我的业务逻辑的实现细节)。

在这返回 true 之后,我们调用 switchMap 来返回一个为 true 的 Observable。

2022-03-08