Angular-CLI中的HMR和NGRX

6

我目前正在使用一个angular-cli项目(1.0.0-beta.25.5)和ngrx来管理状态。我已经按照this article的说明成功实现了热模块替换,但是我还没有找到一种在发生热模块替换时保持状态的方法。

我看到了以下内容,但是无法使其工作或获取灵感:

有没有人对如何解决这个问题有任何想法或建议?我希望继续使用cli,因此需要找到一种与之集成的方法。

编辑:在这里也找到了一个遇到相同问题的人 https://github.com/ngrx/store/issues/311


我已经使用https://github.com/btroncone/ngrx-store-localstorage实现了一个临时解决方案,您可以选择全部或部分状态放入本地存储。您可以在设置中选择从本地存储重新启动,因此当hmr启动时,状态会被重新获取。然而,这并不能回答如何在不依赖于本地存储的情况下在代码中实现此操作的问题。 - Monkeeman69
1个回答

2
我知道这是死灵法术;P 但对于一些人来说,这仍然可能有用。
TL;DR
你错过了angular-class HMR的一个很重要的部分,那就是metareducer用于设置完整状态。
以下是我如何使用HMR的实现方式,其中包含了一个示例链接https://github.com/gdi2290/angular-hmr Metareducer 首先,您需要一个metareducer来处理设置整个状态的操作。
// make sure you export for AoT
export function stateSetter(reducer: ActionReducer<any>): ActionReducer<any> {
  return function(state: any, action: any) {
    if (action.type === 'SET_ROOT_STATE') {
      return action.payload;
    }
    return reducer(state, action);
  };
}

let _metaReducers: MetaReducer<fromRoot.State, any>[] = [];
if (environment.hmr) {
  _metaReducers = [stateSetter];
}

export const metaReducers = _metaReducers;

当为NgModule注册StoreModule.forRoot时,请记得注册该元减数数组。
StoreModule.forRoot(reducers, { metaReducers })

AppModule

对于 AppModule,您需要定义 hmrOnInit、hmrOnDestroy 和 hmrAfterDestroy 方法。

  • hmrOnInit 加载状态
  • hmrOnDestroy 写入状态(请注意,ngrx store.take(1) 实际上是同步的,这在 ngrx 的 github 问题中有提到,目前无法找到具体位置)。
  • hmrAfterDestroy 清理现有组件元素
export class AppModule {
  constructor(
    private appRef: ApplicationRef,
    private store: Store<fromRoot.State>
  ) { }

  public hmrOnInit(store) {
    if (!store || !store.state) {
      return;
    }
    // restore state
    this.store.dispatch({ type: 'SET_ROOT_STATE', payload: store.state });
    // restore input values
    if ('restoreInputValues' in store) {
      const restoreInputValues = store.restoreInputValues;
      // this isn't clean but gets the job done in development
      setTimeout(restoreInputValues);
    }
    this.appRef.tick();
    Object.keys(store).forEach(prop => delete store[prop]);
  }

  public hmrOnDestroy(store) {
    const cmpLocation = this.appRef.components.map(
      cmp => cmp.location.nativeElement
    );
    let currentState: fromRoot.State;
    this.store.take(1).subscribe(state => (currentState = state));
    store.state = currentState;
    // recreate elements
    store.disposeOldHosts = createNewHosts(cmpLocation);
    // save input values
    store.restoreInputValues = createInputTransfer();
    // remove styles
    removeNgStyles();
  }

  public hmrAfterDestroy(store) {
    // display new elements
    store.disposeOldHosts();
    delete store.disposeOldHosts;
  }
}

更多详细信息请参见https://github.com/gdi2290/angular-hmr


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接