首页 文章

angular-cli hmr和ngrx

提问于
浏览
6

我目前正在使用带有ngrx的angular-cli项目(1.0.0-beta.25.5)来管理状态 . 我已经关注this article并设法让热模块更换工作,但是当发生这种情况时我还没有找到维持状态的方法 .

我见过以下但是无法获得任何工作或获取灵感:

有没有人对如何处理这个有任何想法或建议?我希望继续使用cli,因此需要找到一种与此相结合的方法 .

编辑:在这里找到有同样问题的人https://github.com/ngrx/store/issues/311

1 回答

  • 1

    我知道这是死灵法术; P但是对于一些人来说这仍然有用 .

    TL; DR

    你从角度级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时,请记住注册该metareducer数组 .

    StoreModule.forRoot(reducers, { metaReducers })
    

    AppModule

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

    • hmrOnInit加载状态

    • hmrOnDestroy写入状态(注意ngrx store.take(1)实际上是同步它's listed somewhere in the ngrx github issues, can'似乎找到了atm) .

    • 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

相关问题