当 ngrx 中状态的其他部分发生变化时,将触发日期订阅
Date subscription get triggered when other part of the state change in ngrx
我有一个 start
和 end
属性,它们将日期存储在我的 state
中。任何时候州的其他部分发生变化我的 subscription
start
和 end
日期被触发。
这是我的订阅
this.subs.sink = this.store
.select(fromTransactionReducer.selectStartAndEndDate)
.subscribe((date) => {
console.log("range", date);
this.range.setValue({
start: date.start,
end: date.end,
});
});
这是选择器
export const selectStartAndEndDate = createSelector(
selectTransactionState,
(state) => ({ start: state.start, end: state.end })
);
这是 dateRange reducer
on(transactionActions.UpdateDateRange, (state, { start, end }) => ({
...state,
start,
end,
})),
这是日期范围操作
export const UpdateDateRange = createAction(
"[Transaction Page] Update Date Range",
props<{ start: Date; end: Date }>()
);
这是我的状态
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,
};
任何时候我发送不同的 action
,例如 this.store.dispatch(transactionActions.ResetPageIndex());
,我的 subscription
日期都会被触发。
这是为什么?
在我的减速器中,我只更新 start
和 end
调度 UpdateDateRange
操作的日期。
ngrx select
运算符利用 rxjs distinctUntilChanged
运算符来确保选择器仅在其结果发生变化时才发出。参考这里的源代码:https://github.com/ngrx/platform/blob/a6fe92df3134b7a589a2e95abe0aea183b411f03/modules/store/src/store.ts#L249
默认distinctUntilChanged
使用相等比较器(参考https://www.learnrxjs.io/learn-rxjs/operators/filtering/distinctuntilchanged)并注意'object references must match!'
现在到您的 selectStartAndEndDate
选择器 - 它 returns 一个 对象 。
此外,它 returns 每次执行时都是一个对象的 新实例 。因此,distinctUntilChanged
中的比较总是失败,所以选择器总是发出。
如何解决:
// 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
我有一个 start
和 end
属性,它们将日期存储在我的 state
中。任何时候州的其他部分发生变化我的 subscription
start
和 end
日期被触发。
这是我的订阅
this.subs.sink = this.store
.select(fromTransactionReducer.selectStartAndEndDate)
.subscribe((date) => {
console.log("range", date);
this.range.setValue({
start: date.start,
end: date.end,
});
});
这是选择器
export const selectStartAndEndDate = createSelector(
selectTransactionState,
(state) => ({ start: state.start, end: state.end })
);
这是 dateRange reducer
on(transactionActions.UpdateDateRange, (state, { start, end }) => ({
...state,
start,
end,
})),
这是日期范围操作
export const UpdateDateRange = createAction(
"[Transaction Page] Update Date Range",
props<{ start: Date; end: Date }>()
);
这是我的状态
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,
};
任何时候我发送不同的 action
,例如 this.store.dispatch(transactionActions.ResetPageIndex());
,我的 subscription
日期都会被触发。
这是为什么?
在我的减速器中,我只更新 start
和 end
调度 UpdateDateRange
操作的日期。
ngrx select
运算符利用 rxjs distinctUntilChanged
运算符来确保选择器仅在其结果发生变化时才发出。参考这里的源代码:https://github.com/ngrx/platform/blob/a6fe92df3134b7a589a2e95abe0aea183b411f03/modules/store/src/store.ts#L249
默认distinctUntilChanged
使用相等比较器(参考https://www.learnrxjs.io/learn-rxjs/operators/filtering/distinctuntilchanged)并注意'object references must match!'
现在到您的 selectStartAndEndDate
选择器 - 它 returns 一个 对象 。
此外,它 returns 每次执行时都是一个对象的 新实例 。因此,distinctUntilChanged
中的比较总是失败,所以选择器总是发出。
如何解决:
// 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