Условно возвращаемое наблюдаемое <Action>в эффекте Ngrx - PullRequest
0 голосов
/ 25 октября 2018

В настоящее время я выполняю рефакторинг своего кода, чтобы включить магазин ngrx.Чтобы минимизировать количество вызовов API моего действия LoadDeals (), я проверяю эффект, если хранилище пусто.Только если он пуст, продолжайте и сделайте вызов API.Сначала я попытался использовать этот шаблон, найденный здесь на SO (https://stackoverflow.com/a/50527652/2879771).

). Я понял, что недостатком является то, что каждый вызов LoadDeals () игнорируется, если в хранилище есть данные. Чтобы иметь возможность форсироватьзагрузить, я включил необязательную булеву полезную нагрузку в класс LoadDeals (). Если для этого параметра установлено значение true, вызовите API.

Вот моя первая попытка

@Effect() loadDeals$: Observable<Action> = this._actions$.pipe(
    ofType<LoadDeals>(actions.LOAD_DEALS),
    withLatestFrom(this._store.pipe(select(getDealsLoaded))),
    switchMap(([action, hasLoaded]) => {
        if (!hasLoaded || action.force) {
            return this._deals.deals.pipe(
                map(deals => new LoadDealsSuccess(deals)),
                catchError(error => of(new LoadDealsFail(error)))
            );
        } else {
            return of(new LoadDealsSkip());
        }
    })
);

Но это приводит к следующей ошибке:

    Argument of type '([action, hasLoaded]: [LoadDeals, boolean]) => Observable<LoadDealsSuccess | LoadDealsFail> | Observable<LoadDealsSkip>' is not assignable to parameter of type '(value: [LoadDeals, boolean], index: number) => ObservableInput<LoadDealsSuccess | LoadDealsFail>'.
  Type 'Observable<LoadDealsSuccess | LoadDealsFail> | Observable<LoadDealsSkip>' is not assignable to type 'ObservableInput<LoadDealsSuccess | LoadDealsFail>'.
    Type 'Observable<LoadDealsSkip>' is not assignable to type 'ObservableInput<LoadDealsSuccess | LoadDealsFail>'.
      Type 'Observable<LoadDealsSkip>' is not assignable to type 'Iterable<LoadDealsSuccess | LoadDealsFail>'.
        Property '[Symbol.iterator]' is missing in type 'Observable<LoadDealsSkip>'.

Вот мои предложения .action.ts

import { Action } from '@ngrx/store';
import { ITmsCpRecord } from '@models/cp';

export enum DealsActionTypes {
    LOAD_DEALS = '[Deals] Load Deals',
    LOAD_DEALS_FAIL = '[Deals API] Load Deals Fail',
    LOAD_DEALS_SUCCESS = '[Deals API] Load Deals Success',
    LOAD_DEALS_SKIP = '[Deals Store] Load Deals Skip (cached)'
}

export class LoadDeals implements Action {
    readonly type = DealsActionTypes.LOAD_DEALS;
    constructor(public force: boolean = false) {}
}
export class LoadDealsFail implements Action {
    readonly type = DealsActionTypes.LOAD_DEALS_FAIL;
    constructor(public payload: any) {}
}
export class LoadDealsSuccess implements Action {
    readonly type = DealsActionTypes.LOAD_DEALS_SUCCESS;
    constructor(public payload: ITmsCpRecord[]) {}
}
export class LoadDealsSkip implements Action {
    readonly type = DealsActionTypes.LOAD_DEALS_SKIP;
}

// action types
export type DealsAction = LoadDeals|LoadDealsFail|LoadDealsSuccess|LoadDealsSkip;

Поэтому я разделил его на отдельные эффекты, слушая одно и то же действие, но с другим оператором фильтра.Это отлично работает.Хотя я не хотел бы разбивать его, потому что это какой-то избыточный код.

Кто-то видит мою ошибку?Ура

@Effect() loadDeals$: Observable<Action> = this._actions$.pipe(
    ofType<LoadDeals>(actions.LOAD_DEALS),
    withLatestFrom(this._store.pipe(select(getDealsLoaded))),
    filter(([action, hasLoaded]) => !hasLoaded || action.force),
    switchMap(() => {
        return this._deals.deals.pipe(
            map(deals => new LoadDealsSuccess(deals)),
            catchError(error => of(new LoadDealsFail(error)))
        );
    })
);

@Effect() loadDealsSkip$: Observable<Action> = this._actions$.pipe(
    ofType<LoadDeals>(actions.LOAD_DEALS),
    withLatestFrom(this._store.pipe(select(getDealsLoaded))),
    filter(([action, hasLoaded]) => hasLoaded && !action.force),
    switchMap(() => of(new LoadDealsSkip()))
);

1 Ответ

0 голосов
/ 25 октября 2018

Вам, вероятно, не понравится этот ответ, но я бы предложил создать 2 действия для этого.Одно действие загрузки, как у вас уже есть, и другое действие принудительной загрузки.

Это также будет означать создание 2 эффектов, но во втором вам не придется выбирать из магазина.

...