Как создать кеширование с NGRX? - PullRequest
0 голосов
/ 02 мая 2020

Я создаю копию WhatsApp, чтобы иметь возможность узнать больше, и она попадает в неизвестность здесь, а именно:

В реальном WhatsApp, когда мы нажимаем сообщение друга на с правой стороны, он автоматически уже дает нам всю информацию с левой стороны, правильно?

Проблема, которая происходит со мной, состоит в том, что я делаю запрос к бэкэнду, чтобы он изменил свойство isClicked пользователя и с этим запрос занимает X секунд и, таким образом, генерирует задержку при отображении информации с правой стороны.

Я даже думал о том, чтобы поместить свойство isClicked в EntityAdapter, но это не сработает, потому что это было бы «глобальным» без ссылки на конкретного пользователя, но сразу на всех пользователей.

Что я могу сделать, ребята?

ЗАДЕРЖКА enter image description here

МОЙ РЕДУКТОР

export interface State extends EntityState<IPeople> {
    error: IRequestError | null;
    loading: boolean;
}

export const adapter: EntityAdapter<IPeople> = createEntityAdapter<IPeople>({
    selectId: (people) => people.id,
});

const INIT_STATE: State = adapter.getInitialState({
    error: null,
    loading: true,
});

const peopleReducer = createReducer(
    INIT_STATE,
    on(fromPeopleAction.GET_ALL_SUCCESS, fromPeopleAction.CREATE_ALL_SUCCESS, (state, { peoples }) => adapter.addMany(peoples, { ...state, loading: false })),
    on(fromPeopleAction.UPDATE_PARTIAL_WITH_CLICK_SUCCESS, (state, { updates }) => adapter.updateMany(updates, { ...state, loading: false })),
    on(fromPeopleAction.GET_ALL_FAIL, fromPeopleAction.CREATE_ALL_FAIL, fromPeopleAction.UPDATE_PARTIAL_WITH_CLICK_FAIL, (state, { error }) => ({
        ...state,
        error,
        loading: false,
    }))
);

export function reducer(state: State | undefined, action: Action) {
    return peopleReducer(state, action);
}

МОИ ЭФФЕКТЫ

updatePartialWithClick$: Observable<Action> = createEffect(() =>
        this.action$.pipe(
            ofType(fromPeopleActions.UPDATE_PARTIAL_WITH_CLICK),
            withLatestFrom(this.selectorsService.userFriendClicked),
            switchMap(([action, userFriendClicked]) => {
                if (action.updates.id !== userFriendClicked.id) {
                    const peoples: Update<IPeople>[] = [];
                    const https: Observable<Update<IPeople>>[] = [];

                    peoples.push(action.updates);
                    peoples.push({
                        ...userFriendClicked,
                        changes: {
                            isClicked: false,
                        },
                    });

                    peoples.forEach((people) => https.push(this.backendService.updatePartial(people)));

                    return forkJoin(https).pipe(
                        map(() => fromPeopleActions.UPDATE_PARTIAL_WITH_CLICK_SUCCESS({ updates: peoples })),
                        catchError((error) => of(fromPeopleActions.UPDATE_PARTIAL_WITH_CLICK_FAIL({ error: this.requestHandlerService.getError(error) })))
                    );
                }

                return of(
                    fromPeopleActions.UPDATE_PARTIAL_WITH_CLICK_FAIL({
                        error: {
                            status: 400,
                            statusText: 'The server cannot process this request.',
                            url: `${environment.backend.url}/${environment.backend.port}`,
                            ok: false,
                            name: 'Bad Request',
                            message: 'The server cannot process this request, as this item is already selected.',
                        },
                    })
                );
            })
        )
    );

ЭФФЕКТ МОЕГО ВЫЗОВА

@Component({
    selector: 'app-user-talk-controller-container',
    template: `
        <aside>
            <header>
                <app-user-container-controller
                    type="USER_TALK_CONTROLLER_CONTAINER"
                    [iconList]="iconList"
                    [username]="user.name"
                    [avatarSrc]="user.avatar.src"
                    [avatarAlt]="user.avatar.alt"
                ></app-user-container-controller>
            </header>
            <section>
                <app-search-container></app-search-container>
            </section>
            <footer>
                <app-user-friend-talk-list (friendClick)="openTalkContainer($event)" [talkList]="talkList"></app-user-friend-talk-list>
            </footer>
        </aside>
    `,
    styleUrls: ['./user-talk-controller-container.component.scss'],
})
export class UserTalkControllerContainerComponent implements OnInit {
    @Input() user: IPeople;
    @Input() talkList: IPeopleTalkList[];
    iconList: IconList[] = [{ name: 'status' }, { name: 'chat' }, { name: 'more-options' }];
    protected subscriber = new Subscriber<IPeople>();

    constructor(protected readonly dispatchService: PeopleDispatchService, protected readonly selectorsService: PeopleSelectorsService) {}

    ngOnInit(): void {}

    openTalkContainer(friend: IPeople): void {
        this.dispatchService.updatePartialWithClick({
            id: friend.id,
            changes: {
                isClicked: true,
            },
        });
    }
}
...