2017-01-16 121 views
3

我目前正在使用一個angular-cli項目(1.0.0-beta.25.5)和ngrx來管理狀態。我跟着this article,並設法讓熱模塊更換工作,但我還沒有找到一種方法來維護狀態,當這種情況發生。angular-cli hmr和ngrx

我看到了下面的,但一直未能得到任何工作或靈感:

有沒有人有任何想法或建議如何解決這個問題?我希望繼續使用cli,所以需要找到一種與此融合的方式。

編輯:發現有人在這裏同樣的問題,以及https://github.com/ngrx/store/issues/311

+0

我以https://github.com/btroncone/ngrx-store-localstorage實現的臨時解決方案您可以在其中選擇全部或部分狀態以放入本地存儲。您可以選擇從設置中的本地存儲中進行補充水分,因此當hmr踢入狀態時會恢復。但是,這並不能回答我如何在不依賴本地存儲的情況下在代碼中執行此操作。 – Monkeeman69

回答

0

我知道這是巫術; 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

對於您需要定義hmrOnInit,hmrOnDestroy & hmrAfterDestroy方法中的AppModule。

  • hmrOnInit加載狀態
  • hmrOnDestroy並將狀態(注意NGRX store.take(1)是真的 同步它的某處NGRX github上列出的問題,似乎無法尋找到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