2017-01-16 5 views
3

В настоящее время я использую проект angular-cli (1.0.0-beta.25.5) с ngrx для управления состоянием. Я последовал за this article и смог получить горячую замену модуля, однако я не нашел способ поддерживать состояние, когда это происходит.angular-cli hmr and ngrx

я видел следующее, но не смогли получить что-нибудь работает или черпать вдохновение:

Есть ли у кого-нибудь идеи или предложения относительно того, как подойти к этому? Я хочу продолжать использовать cli, поэтому вам нужно найти способ интеграции с этим.

Edit: Найдено кто-то с той же проблемой здесь, а https://github.com/ngrx/store/issues/311

+0

Я реализовал временное решение с помощью https://github.com/btroncone/ngrx-store-localstorage где вы можете выбрать все или частичное состояние для локального хранения. Вы можете выбрать регидратацию из локального хранилища в настройках, поэтому, когда hmr kicks in state будет восстановлен.Это, однако, не отвечает, как я могу это сделать в коде, не полагаясь на локальное хранилище. – Monkeeman69

ответ

0

Я знаю, что это некромантия; P Но для некоторых это еще может быть полезным.

TL; DR

То, что вы пропустили от углового класса ГМР был вполне вероятно 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; 

При регистрации StoreModule.forRoot для NgModule зарегистрируйте этот массив metareducer.

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

Смежные вопросы