我目前正在调度一个事件以从后端检索所有数据,并且通过这个调度我普及了状态副本。
到目前为止一切都很好,问题是如果后端没有任何东西我需要调度一个事件来在其上创建数据并在状态的新副本中创建数据。
为此我使用了一个选择器来检查状态中是否已经存在某些东西,因为如果后端会有一个,他的问题是结果到达多个并且延迟与下图相同:
应用程序组件
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
title = 'webwhatsapp';
protected peoples: Array<IPeople> = [
{ id: '0', isMain: true, name: 'THIAGO DE BONIS CARVALHO SAAD SAUD', avatar: 'assets/users/thiagobonis.jpg', messages: null },
{ id: '1', isMain: false, name: 'BILL GATES', avatar: 'assets/users/billgates.jpg', messages: null },
{ id: '2', isMain: false, name: 'STEVE JOBS', avatar: 'assets/users/stevejobs.jpg', messages: null },
{ id: '3', isMain: false, name: 'LINUS TORVALDS', avatar: 'assets/users/linustorvalds.jpg', messages: null },
{ id: '4', isMain: false, name: 'EDSGER DIJKSTRA', avatar: 'assets/users/dijkstra.jpg', messages: null },
];
constructor(private readonly peopleDispatchService: PeopleDispatchService, private readonly peopleSelectorsService: PeopleSelectorsService) {}
ngOnInit(): void {
this.peopleDispatchService.getAll();
this.peopleSelectorsService.total.subscribe((total) => {
console.log(total);
if (total === 0) {
// this.peoples.forEach((people) => this.peopleDispatchService.create(people));
} else {
}
});
}
}
减速机
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, (state, { peoples }) => adapter.addMany(peoples, { ...state, loading: false })),
on(fromPeopleAction.GET_ALL_FAIL, (state, { error }) => ({ ...state, error, loading: false })),
on(fromPeopleAction.CREATE_SUCCESS, (state, { people }) => adapter.addOne(people, { ...state, loading: false })),
on(fromPeopleAction.CREATE_FAIL, (state, { error }) => ({ ...state, error, loading: false })),
on(fromPeopleAction.DELETE_SUCCESS, (state, { id }) => adapter.removeOne(id, { ...state, loading: false })),
on(fromPeopleAction.DELETE_FAIL, (state, { error }) => ({ ...state, error, loading: false }))
);
export function reducer(state: State | undefined, action: Action) {
return peopleReducer(state, action);
}
效果
@Injectable()
export class Effects {
constructor(private action$: Actions, private backend: BackendService, private requestHandler: RequestHandlerService) {}
getAll$ = createEffect(() =>
this.action$.pipe(
ofType(fromPeopleActions.GET_ALL),
mergeMap(() => {
return this.backend.getAll().pipe(
map((peoples) => fromPeopleActions.GET_ALL_SUCCESS({ peoples })),
catchError((error) => of(fromPeopleActions.GET_ALL_FAIL({ error: this.requestHandler.getError(error) })))
);
})
)
);
create$ = createEffect(() =>
this.action$.pipe(
ofType(fromPeopleActions.CREATE),
mergeMap((action) => {
return this.backend.create(action.people).pipe(
map((people) => fromPeopleActions.CREATE_SUCCESS({ people })),
catchError((error) => of(fromPeopleActions.CREATE_FAIL({ error: this.requestHandler.getError(error) })))
);
})
)
);
deleteAll$ = createEffect(() =>
this.action$.pipe(
ofType(fromPeopleActions.DELETE),
mergeMap((action) => {
return this.backend.delete(action.id).pipe(
map(() => fromPeopleActions.DELETE_SUCCESS({ id: action.id })),
catchError((error) => of(fromPeopleActions.DELETE_FAIL({ error: this.requestHandler.getError(error) })))
);
})
)
);
}
选择器
const featureSelector = createFeatureSelector<State>('people');
export const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors(featureSelector);
export const getError = createSelector(featureSelector, (state: State) => state.error);
export const getIsMain = createSelector(featureSelector, (state: State) => {
state.ids.forEach((id: any) => {
if (state.entities[id].isMain) {
return state.entities[id];
}
});
});