angular - Ngrx 重置商店后,组件调度一个动作
问题描述
我已经为我的应用程序实现了商店。注销后我想重置商店。但有一个问题。
假设我有以下状态:
subjects: {
subjectsLoaded: true
}
在组件中,我订阅了这样的商店:
this.store.pipe(
select(areSubjectsLoaded),
tap((subjectsLoaded) => {
if (!subjectsLoaded) {
this.store.dispatch(loadSubjects());
console.log('Dispatching Subjects because they are not Loaded');
}
}),
filter(subjectsLoaded => subjectsLoaded),
takeUntil(this.unsubscribe$)
).subscribe();
注销并重置商店后,它将如下所示:
subjects: {
subjectsLoaded: false
}
由于我订阅了组件中的更改,因此将进行操作调度。但我不知道如何防止这种情况。我也是takeUntil
为了在组件销毁后不接收数据
有一个小演示:
为了清除我正在使用 metaReducers 的商店:
export const metaReducers: MetaReducer<AppState>[] = [clearState];
export function clearState(reducer: ActionReducer<AppState>): ActionReducer<AppState> {
return (state: AppState, action: Action): AppState => {
if (action.type === '[Toolbar] User Logout') {
console.log('Clear state: ',state);
state = undefined;
}
return reducer(state, action);
};
}
解决方案
我认为您必须使用除 之外的其他内容undefined
,因为正如您所见,您无法再区分“状态尚未初始化”和“状态必须重置”。
您可以使用 asymbol
来区分这些状态。
export const RESET_STATE = Symbol('reset state');
// your meta-reducer
state = RESET_STATE;
return state;
现在您可以通过这种方式识别它们:
this.store.pipe(
filter(state => state !== RESET_STATE),
select(areSubjectsLoaded),
/* ... */
)
如果您不想重复自己,您可以根据该逻辑创建一个选择器,并在您的其他选择器中使用它。
推荐阅读
- azure-sql-database - adf v2 链接服务连接池
- alloy - 是否可以在签名事实中使用无点表达式?
- docker - 在 giblab-ci.yaml 中,作业上的“服务”是否会在给定相同“别名”的情况下生成单独的实例?
- python - 将代码 kivy.py 转录为 kivy.py - .kv (TextCheckBox)
- python - 在keras中将张量转换为numpy数组
- c++ - C++ 通过多个函数传递模板参数
- ios - 收到推送通知时 iOS 13 崩溃?
- python - 如何加载我自己的图像而不是 Mnist 数据集图像?
- php - 如何修复在 laravel 5 中显示为符号的图像
- flutter - 颤振的 LiveData