NgRx效果不适用于Angular Resolver

时间:2018-06-27 14:14:49

标签: angular angular5 ngrx

我正在尝试在实际显示页面之前加载一些特定的页面数据。我设法使用Angular Resolver做到了这一点。为简单起见,我基本上是在resolve方法中调度动作并返回成功动作。

@Injectable()
export class NotificationsResolver implements Resolve<Action> {
constructor(
    private _store: Store<fromRoot.State>,
    private _actions: Actions,
) { }

public resolve(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Action> {
    this._store.dispatch(new notificationActions.GetNotifications());
    return this._actions.ofType(NotificationActionTypes.GET_NOTIFICATIONS_SUCCESS).take(1);
}

}

我正在执行以下操作:

@Effect()
    getNotifications$ = this._actions$
        .ofType(NotificationActionTypes.GET_NOTIFICATIONS)
        .withLatestFrom(this._store$)
        .switchMap(([, storeState]): any => {
            if (storeState.notificationsState.notifications.length > 0) {
                return [new notificationActions.GetNotificationsSuccess(storeState.notificationsState.notifications)];
            }
            return this._apiClient.getNotifications(storeState.initState.organizationId)
                .map((notifications: Notification[]) => new notificationActions.GetNotificationsSuccess(notifications))
                .catch(error => of(new notificationActions.GetNotificationsFail(error)));
        });

删除if语句可使整个程序按预期工作,但是我不想每次用户导航到此路线时都调用API。 基本上,我正在检查我的商店以查看是否已经有了通知列表,以免两次调用API。如果可以,我将其返回,如果列表为空,则将从后端获取它们。

当我从后端获取列表时,一切正常,我被重定向到显示该通知列表的通知/通知。但是,当我从ngrx存储中获取它时,尽管我看到了按应有的方式调度动作(GET_NOTIFICATIONS-> GET_NOTIFICATIONS_SUCCESS),但我没有被重定向到我/通知中。

为此操作和路由附加API调用方法和reducer:

 public getNotifications(organizationId: UUID): Observable<any> {
    const headers = new HttpHeaders()
        .set('Content-Type', 'application/json')
        .set('Authorization', `Bearer ${this._authService.getAccessToken()}`);
    return this._httpClient.get(`${this._baseUri}/organizations/${organizationId}/notifications`, { headers: headers });

case NotificationActionTypes.GET_NOTIFICATIONS_SUCCESS: {
            return Object.assign({}, state, {
                loading: false,
                notifications: [...action.payload],
            });
        }



{ path: 'notifications', component: NotificationsComponent, resolve: {notifications: NotificationsResolver } }

任何帮助都会很棒。谢谢

1 个答案:

答案 0 :(得分:0)

我设法找到了解决此问题的方法。我在状态中添加了一个名为“已加载”的新属性,该属性最初设置为false。在GetNotificationsSuccess上,将其设置为true。这导致路由解析器发生以下更改。

public resolve(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
        this._store.dispatch(new notificationActions.GetNotifications());
        return this.waitForLoading()
            .pipe(
                switchMap(() => this.waitForLoading())
            );
    }

waitForLoading(): Observable<boolean> {
    return this._store.select(state => state.notificationsState.loaded)
        .pipe(
            filter(loaded => loaded),
            take(1)
        );
}

如果有人有不同的解决方案,或者可以告诉我第一个示例为何不起作用,我将很高兴。