Tengo una propiedad de start y end que almacena una fecha en mi state . Cada vez que se cambia otra parte del estado, se activa mi subscription para la fecha de start y end .
esta es mi suscripcion
this.subs.sink = this.store .select(fromTransactionReducer.selectStartAndEndDate) .subscribe((date) => { console.log("range", date); this.range.setValue({ start: date.start, end: date.end, }); });este es el seleccionador
export const selectStartAndEndDate = createSelector( selectTransactionState, (state) => ({ start: state.start, end: state.end }) );este es el reductor dateRange
on(transactionActions.UpdateDateRange, (state, { start, end }) => ({ ...state, start, end, })),esta es la acción de intervalo de fechas
export const UpdateDateRange = createAction( "[Transaction Page] Update Date Range", props<{ start: Date; end: Date }>() );este es mi estado
export interface State { transaction: Transaction[]; cursors: Cursor; totalTransactions: number; loading: boolean; errorMessage: string; formErrorMessage: string; items_per_page: number; pageSizeOptions: number[]; pageIndex: number; searchKey: string; formMessage: string; start: Date; end: Date; trans_type: string; base_type: string; } export const initialState: State = { transaction: [], cursors: { after: "", before: "", hasNext: false, hasPrevious: false, }, totalTransactions: 0, loading: false, errorMessage: null, formErrorMessage: null, items_per_page: 5, pageSizeOptions: [2, 3, 5, 10, 15], pageIndex: 0, searchKey: "", formMessage: "", start: null, end: null, trans_type: null, base_type: null, }; Cada vez que envío una action diferente, por ejemplo this.store.dispatch(transactionActions.ResetPageIndex()); , mi subscription para la fecha se activa.
porqué es eso ?
En mi reductor, solo actualizo la fecha de start y end cuando se envía la acción UpdateDateRange .
El operador de select ngrx utiliza el operador rxjs distinctUntilChanged para garantizar que un selector solo se emita si su resultado ha cambiado. Consulte el código fuente aquí: https://github.com/ngrx/platform/blob/a6fe92df3134b7a589a2e95abe0aea183b411f03/modules/store/src/store.ts#L249
De forma predeterminada, distinctUntilChanged utiliza un comparador de igualdad (consulte https://www.learnrxjs.io/learn-rxjs/operators/filtering/distinctuntilchanged ) y tenga en cuenta que las referencias de objetos deben coincidir.
Ahora a su selector selectStartAndEndDate : devuelve un objeto .
Además, devuelve una nueva instancia de un objeto cada vez que se ejecuta. Debido a esto, la comparación en distinctUntilChanged siempre falla, por lo que el selector siempre emite.
Como resolverlo:
// returned date will be considered equal next time so selector won't fire export const selectStartDate = createSelector( selectTransactionState, (state) => state.start ); // same here export const selectEndDate = createSelector( selectTransactionState, (state) => state.end ); // as input selectors didn't change, this won't fire either export const selectStartAndEndDate = createSelector( selectStartDate, selectEndDate , (start, end) => ({ start, end }) );Stackblitz: https://codesandbox.io/s/so-ngrx-selector-emit-1zxg1?file=/src/app/store/selectors.ts