6

CanDeactivate我试图通过使用(如果表单脏且未保存)来限制用户导航离开当前页面。当我们点击任何链接时,Router_Navigation事件被调用并且它正在更新商店中的路由器状态,如果我取消模式弹出时的页面导航(从可以停用),Router_Cancel事件正在被调用,但当前路由器状态是没有更新(它仍然指向其他页面)。

我在ngrx文档中看到了这一点:

ROUTER_CANCEL 和 ROUTER_ERROR 包含导航前的存储状态。使用之前的状态来恢复存储的一致性。

有人可以帮我了解如何从Router_cancelAction 中获取以前的状态。

谢谢

4

2 回答 2

4

我通过创建一个 applicationRouter 状态来维护当前和以前的路由来解决这个问题,每当 ngrx 路由器调度一个 ROUTER_NAVIGATION 事件时,我都会监听它并更新我的 applicationRouterState。

在每一点 applicationRouter 将只有两个路由器事件(当前和先前状态)。

并且每当触发 Router_Cancel 时,我都会切换先前的路由器和当前的路由器状态。

PFB,解决方案:

@Effect()
    navigationListener$ = this.actions$.ofType('ROUTER_NAVIGATION')
        .pipe(
            switchMap((routerNavigationAction: RouterNavigationAction<RouterDefinition>) => {
                return of(routerNavigationAction).pipe(
                    withLatestFrom(this._routerNavigationData$),
                    map(([action, routerNavData]: [RouterNavigationAction<RouterDefinition>, RouterState]) => {
                        // TODO: Move this logic to Reducer
                        if (!(routerNavData.currentRouter && routerNavData.currentRouter.url
                            && routerNavData.previousRouter && routerNavData.previousRouter.url)) {
                            routerNavData.previousRouter = routerNavData.currentRouter =  action.payload.routerState;
                        } else {
                            routerNavData.previousRouter = routerNavData.currentRouter;
                            routerNavData.currentRouter = action.payload.routerState;
                        }
                        return new fromActions.MaintainPrevCurrRouterStateAction(routerNavData);
                    })
                );
            })
        );

这是我的状态对象:

export interface RouterDefinition {
    url: string;
    queryParams: Params;
    params: Params;
    segments: string[];
}
export interface RouterState {
    currentRouter: RouterDefinition;
    previousRouter: RouterDefinition;
}
于 2018-04-13T18:42:35.877 回答
3

我使用 angrx/effect来存储最近的两个ROUTER_NAVIGATION动作,并在我得到 a 时重新调度前一个动作,ROUTER_CANCEL以便ROUTER_ERROR路由器状态完全恢复。

@Injectable()
export class RouterEffects {
    private previousRouterNavigationAction: RouterNavigationAction<
        RouterStateUrl
    >;
    private currentRouterNavigationAction: RouterNavigationAction<
        RouterStateUrl
    >;

    @Effect({ dispatch: false })
    save$: Observable<Action> = this.actions$.pipe(
        ofType(ROUTER_NAVIGATION),
        switchMap((action: RouterNavigationAction<RouterStateUrl>) => {
            this.previousRouterNavigationAction = this.currentRouterNavigationAction;
            this.currentRouterNavigationAction = { ...action };
            return Observable.empty();
        })
    );

    @Effect()
    load$: Observable<Action> = this.actions$.pipe(
        ofType(ROUTER_CANCEL, ROUTER_ERROR),
        switchMap(action => Observable.of(this.previousRouterNavigationAction))
    );

    constructor(private actions$: Actions) {}
}
于 2018-05-23T07:37:03.530 回答