从@ ngrx / db中补充@ ngrx / store

时间:2017-10-18 13:16:11

标签: angular ngrx reducers

我希望在页面加载/引导时重新@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中使用它?

1 个答案:

答案 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}}的简短博客文章。