[英]How to combine ngrx entities using effects (which are returned periodically as a result of call from the frontend)?
[角度] [javascript] [ngrx/實體] [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);
如果您需要您的效果每秒發送一個請求 - 您需要interval
運算符。
//effects.ts
loadCourierItems$ = createEffect(() =>
this.actions$.pipe(
ofType(CourierItemActions.loadCourierItems),
exhaustMap(action => interval(1000).pipe(
startWith(0),
exhaustMap(step =>
this.defaultService.getCourierItems(
action.limit,
action.start + step * 1000,
action.end + step * 1000,
).pipe(
map(courierItems => CourierItemActions.loadCourierItemsSuccess({ courierItems })),
catchError(error =>
of(CourierItemActions.loadCourierItemsFailure({ error }))
)
)
),
),
takeUntil(this.actions$.pipe(ofType(CourierItemActions.pauseStreamingCourierItems))),
repeat(),
)
)
//app.component.ts
constructor(private store: Store<CourierItemsState>) {
}
ngOnInit() {
this.store.dispatch(loadCourierItems());
this.courierItems$ = this.store.pipe(select(selectCourierItems));
}
ngOnDestroy() {
this.store.dispatch(stopCourierItems());
}
您可能需要使用upsertMany:在集合中添加或更新多個實體。 支持部分更新。
on(CourierItemActions.loadCourierItemsSuccess,
(state, action) => adapter.upsertMany(action.courierItems, state)
),
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.