[angular] [javascript] [ngrx / entity] [ngrx / эффекты] [rxjs]
Ниже приведены мои эффекты. Используется для извлечения данных из серверной части.
//effects.ts
loadCourierItems$ = createEffect(() =>
this.actions$.pipe(
ofType(CourierItemActions.loadCourierItems),
mergeMap(action =>
this.defaultService.getCourierItems(
).pipe(
map(CourierItems => CourierItemActions.loadCourierItemsSuccess({ CourierItems })),
catchError(error =>
of(CourierItemActions.loadCourierItemsFailure({ error }))
)
)
)
)
)
Ниже приводится мой селектор
//selector.ts
export const selectCourierItemState = createFeatureSelector<CourierItemState>(
CourierItemsFeatureKey
);
export const selectCourierItems = createSelector(selectCourierItemState, selectAll);
Это компонент, в который я отправляю действие для получения данных в первый раз:
//app.component.ts
constructor(private store: Store<CourierItemsState>) {
this.store.dispatch(loadCourierItems())
}
ngOnInit() {
this.courierItems$ = this.store.pipe(select(selectCourierItems))
}
//template.html
<div *ngFor="let item of courierItems$ | async as courier>
<p>{{courier.name}}</p>
<p>{{courier.loc_cur}}</p>
etc...
</div>
...
Как я могу это сделать?
Чего я хочу добиться, так это того, что я хочу делать новый запрос каждые 1 с эффектом (бэкэнд отправит обратно массив из 10 элементы) Я хочу объединить эти элементы в одну коллекцию объектов.
Обновлено
loadCourierItems$ = createEffect(() =>
this.actions$.pipe(
ofType(CourierItemActions.loadCourierItems),
exhaustMap(action => interval(1000).pipe(
takeUntil(this.actions$.pipe(ofType(CourierItemActions.stopCourierItems))),
exhaustMap(() =>
this.defaultService.getCourierItems(
action.limit,
action.start,
action.end,
).pipe(
map(courierItems => CourierItemActions.loadCourierItemsSuccess({ courierItems })),
catchError(error =>
of(CourierItemActions.loadCourierItemsFailure({ error }))
)
)
)
))
)
)
ДРУГОЕ ОБНОВЛЕНИЕ Если я использую что-то подобное, я могу получать каждую секунду, и коллекция сущностей растет , Но благодаря такому подходу я не могу контролировать запуск / останов.
let date = 1587513626000; // date is required because the backend only sends data with a start and end date
interval(1000).pipe(tap(_ => {
this.store.dispatch(loadStoreItems({ limit: 10, start: date, end: date + 1000 }))
date += 1000
}))
.subscribe()
ОБНОВЛЕНИЕ РЕДУКТОРА
export const reducer = createReducer(
initialState,
on(CourierItemActions.loadCourierItemsSuccess,
(state, action) => adapter.addMany(action.courierItems, state)
),
on(CourierItemActions.loadCourierItemsFailure,
(state, action) => {
return {
...state,
error: action.error
}
}
),
Я пробовал addMany & addAll .. Оба не работают. Только элементы первого вызова попадают в коллекцию сущностей. Но в фоновом режиме запрос все еще продолжается каждые 1 с.
ОБНОВЛЕНИЕ Это селектор.
export const selectCourierItemState = createFeatureSelector<CourierItemState>(
CourierItemsFeatureKey
);
export const selectCourierItems = createSelector(selectCourierItemState, selectAll);