В вашем случае у меня, вероятно, было бы свойство внутри моего магазина, которое указывает, были ли данные уже загружены или нет, например, loaded
. Когда вы в первый раз отправляете действие, которое отправляет и извлекает данные в вашем эффекте, когда данные возвращаются, вы также установите для этого свойства loaded
значение true
. Значение по умолчанию будет false
. Внутри вашего эффекта вы можете использовать withLatestFrom
и выбрать свойство loaded
. Если он установлен на true
, ничего не делать, если он установлен на false
, пойти и получить данные.
Прежде всего измените ProductState
и введите свойство loaded
:
export interface ProductState {
toggleCheckBox: boolean,
products: Product[],
loaded: boolean;
error: string
}
const initialState: ProductState = {
toggleCheckBox: true,
products: [],
loaded: false,
error: ''
};
В вашем редукторе на LoadSuccess
установите для свойства loaded
значение true
:
case ProductActionTypes.LoadSuccess:
return {
...state,
products: [...action.payload],
loaded: true,
error: ''
}
Теперь внутри вашего эффекта проверьте свойство loaded
, а затем извлеките данные в зависимости от его значения:
@Effect()
loadProduct$: Observable<Action> = this.action$.pipe(
ofType(productAction.ProductActionTypes.Load),
withLatestFrom(this.store.pipe(select(fromProduct.getLoaded))),
switchMap(([, loaded]) => {
if (loaded) {
return empty();
}
return this.productService.getProducts().pipe(
map((products) => {
return new productAction.LoadSuccess(products)
}),
catchError(err => of(new productAction.LoadFail(err)))
)
})
);
Это означает, что ваш эффект будет извлекать данные только тогда, когда они еще не загружены, что указывается свойством loaded
в вашем ProductState
.
Проверьте это StackBlitz , чтобы увидеть его в действии. Откройте вкладку «Сеть» консоли разработчика и убедитесь, что запрос выполняется только один раз, а после этого он «кэшируется» из-за свойства loaded
.