我希望在页面加载/引导时重新@ngrx/store
。
我使用@ngrx/db
在浏览器的IndexedDB中保存了以前的状态,我想在我商店的INIT_ACTION
处检索此信息。
要做到这一点,我发现存在metaReducers
喜欢:
export function indexedDBSyncReducer(reducer: ActionReducer<any>): ActionReducer<any> {
return function newReducer(state, action: any) {
if (action.type == 'INITIAL_STATE') {
// Read information to db and set nextState
}
const nextState = reducer(state, action);
return nextState;
};
}
问题是要从@ngrx/db
中检索信息,我需要使用构造函数进行访问。比如this。
metaReducers
是纯函数所以,如何注入Database
提供程序以在我的reducer中使用它?
答案 0 :(得分:2)
您可以将托管类与返回reducer函数的方法一起使用:
@Injectable()
export class AccountReducerFactory {
// here you get your db access (or any managed service) injected
constructor(private dbService: DbService) {}
createReducer() {
return (state: AccountState, action: Action) => {
if(action.type === 'INITIAL_STATE') {
const initialState = this.dbService.readInitialState()
// do something with your initial state
}
}
}
}
然后,您使用注入令牌提供减速器(如here所述)。这是“帐户”功能模块的简化示例:
export const ACCOUNT_REDUCER_TOKEN = new InjectionToken<ActionReducer<Map<string, Account>>>('Account state reducer')
export function getAccountReducer(accountReducerFactory: AccountReducerFactory): ActionReducer<Map<string, Account>> {
// here you create a reducer function with access to other managed services
return accountReducerFactory.createReducer()
}
@NgModule({
imports: [
StoreModule.forFeature('account', ACCOUNT_REDUCER_TOKEN)
],
providers: [
{
provide: ACCOUNT_REDUCER_TOKEN,
// here your AccountReducerFactory class will be instantiated with its deps
deps: [AccountReducerFactory],
useFactory: getAccountReducer
}
]
})
export class AccountModule {
}
这回答了如何在ngrx reducer中访问服务。至于您最初的问题,您将面临另一个难以克服的挑战:indexedDb是异步的,而ngrx初始化不是。我写了一篇关于{{3}}的简短博客文章。