Эффект NgRx не работает с Angular Resolver - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь загрузить определенные данные страницы перед тем, как отобразить страницу. Мне удалось сделать это с помощью Angular Resolver. Для простоты я в основном отправляю действие и возвращаю успешное действие в методе разрешения.

@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 и редуктора для этого действия и маршрута:

 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 голосов
/ 03 июля 2018

Мне удалось найти решение этой проблемы. Я добавил новое свойство в мое состояние с именем «загружен», которое я изначально установил в false. На GetNotificationsSuccess я установил его в значение true. Это приводит к следующему изменению маршрута Resolver.

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)
        );
}

Если у кого-то есть другое решение или я могу сказать, почему первый пример не работает, я был бы рад.

...