Ngrx - Reducer 无法接收动作
Ngrx - Reducer can't receive action
我正在尝试在应用程序初始化时加载一些缓存的详细信息。我正在使用 angular 的内置 APP_INITIALIZER
提供程序。
在这个提供者中,我运行使用 AppService
的 init 方法并加载那些缓存的信息,调度一些操作。 4 个操作中的 3 个正在正常发送,但是当我尝试发送订单详细信息时,reducer 没有得到这个操作,我无法将订单详细信息传输到存储中。
但是当我查看 redux chrome 扩展时,我能够看到我的动作正在被调度,但是如果我在 reducer 中记录传入的动作,我就看不到我的动作。
奇怪的是,如果我 运行 loadCachedOrderDetails
方法在三秒后使用 setTimeOut 方法,setCachedOrderDetails
操作成功调度..
到底发生了什么?如何正确发送 setCachedOrderDetails
操作?
这里是提供者的完整定义
{
provide: APP_INITIALIZER,
useFactory: (app: AppService) => () => app.init(),
deps: [AppService],
multi: true
}
AppService 初始化方法
init() {
const request = this.loadCachedRequest();
if (request) {
this.loadCurrentLocation(request);
}
this.loadCachedBasketItems();
this.loadCachedOrderDetails();
}
和方法
loadCachedOrderDetails() {
const details = JSON.parse(localStorage.getItem('orderDetails'));
if (details) {
this.store.dispatch(PanelActions.setCachedOrderDetails({details}));
}
}
和我注册减速器的面板商店
@NgModule({
imports: [
StoreModule.forFeature(panelFeatureKey, fromPanel.reducer),
EffectsModule.forFeature([PanelEffects]),
],
exports: [
StoreModule,
EffectsModule
]
})
export class PanelStoreModule {
}
如果您使用 EffectsModule.forFeature
,则表示该模块不是主要模块,您的应用程序已经初始化,并且您的模块很可能被延迟加载或稍后在需要应用程序时初始化。
因此您不能依赖任何 INIT 触发器。因为它们可以在您的功能设置好并准备好收听操作之前发出。
但您可以简单地使用模块的构造函数来分派所需的操作。
@NgModule({
imports: [
StoreModule.forFeature(panelFeatureKey, fromPanel.reducer),
EffectsModule.forFeature([PanelEffects]),
],
exports: [
StoreModule,
EffectsModule,
]
})
export class PanelStoreModule {
constructor(app: AppService) {
app.init();
}
}
或者干脆把effect和reducer移到forRoot
部分。
我正在尝试在应用程序初始化时加载一些缓存的详细信息。我正在使用 angular 的内置 APP_INITIALIZER
提供程序。
在这个提供者中,我运行使用 AppService
的 init 方法并加载那些缓存的信息,调度一些操作。 4 个操作中的 3 个正在正常发送,但是当我尝试发送订单详细信息时,reducer 没有得到这个操作,我无法将订单详细信息传输到存储中。
但是当我查看 redux chrome 扩展时,我能够看到我的动作正在被调度,但是如果我在 reducer 中记录传入的动作,我就看不到我的动作。
奇怪的是,如果我 运行 loadCachedOrderDetails
方法在三秒后使用 setTimeOut 方法,setCachedOrderDetails
操作成功调度..
到底发生了什么?如何正确发送 setCachedOrderDetails
操作?
这里是提供者的完整定义
{
provide: APP_INITIALIZER,
useFactory: (app: AppService) => () => app.init(),
deps: [AppService],
multi: true
}
AppService 初始化方法
init() {
const request = this.loadCachedRequest();
if (request) {
this.loadCurrentLocation(request);
}
this.loadCachedBasketItems();
this.loadCachedOrderDetails();
}
和方法
loadCachedOrderDetails() {
const details = JSON.parse(localStorage.getItem('orderDetails'));
if (details) {
this.store.dispatch(PanelActions.setCachedOrderDetails({details}));
}
}
和我注册减速器的面板商店
@NgModule({
imports: [
StoreModule.forFeature(panelFeatureKey, fromPanel.reducer),
EffectsModule.forFeature([PanelEffects]),
],
exports: [
StoreModule,
EffectsModule
]
})
export class PanelStoreModule {
}
如果您使用 EffectsModule.forFeature
,则表示该模块不是主要模块,您的应用程序已经初始化,并且您的模块很可能被延迟加载或稍后在需要应用程序时初始化。
因此您不能依赖任何 INIT 触发器。因为它们可以在您的功能设置好并准备好收听操作之前发出。
但您可以简单地使用模块的构造函数来分派所需的操作。
@NgModule({
imports: [
StoreModule.forFeature(panelFeatureKey, fromPanel.reducer),
EffectsModule.forFeature([PanelEffects]),
],
exports: [
StoreModule,
EffectsModule,
]
})
export class PanelStoreModule {
constructor(app: AppService) {
app.init();
}
}
或者干脆把effect和reducer移到forRoot
部分。