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