2016-09-05 18 views
8

Używam Angular 2 z ngrx/store. Chcę zresetować wszystkie stany magazynowe, gdy użytkownik wysyła USER_LOGOUT.Jak zresetować wszystkie stany ngrx/store?

Przeczytałem odpowiedź Dana Abramova na How to reset the state of a Redux store?, ale nie wymyśliłem, jak poprawnie napisać rootReducer i gdzie umieścić ją podczas korzystania z ngrx/store.

Czy jest jakiś inny sposób na obsłużenie tego w ngrx/store?

bootstrap(App, [ 
    provideStore(
     compose(
     storeFreeze, 
     storeLogger(), 
     combineReducers 
    )({ 
     router: routerReducer, 
     foo: fooReducer, 
     bar: barReducer 
     }) 
    ) 
    ]); 

Odpowiedz

8

Ta odpowiedź jest specyficzne dla ngrx wersji 2. Pytanie ma another, more recent answer który wyjaśnia, jak to samo można zrobić z ngrx wersji 4.


compose buduje ngrx korzeniowy reduktor.

Argumenty przekazane do compose są funkcjami, które zwracają reduktor - złożony z reduktora, który sam jest przekazywany jako argument. Można skomponować kasowanie sklepu tak:

import { compose } from "@ngrx/core/compose"; 

... 

bootstrap(App, [ 
    provideStore(
    compose(
     storeFreeze, 
     storeLogger(), 
     (reducer: Function) => { 
     return function(state, action) { 
      if (action.type === 'USER_LOGOUT') { 
      state = undefined; 
      } 
      return reducer(state, action); 
     }; 
     }, 
     combineReducers 
    )({ 
     router: routerReducer, 
     foo: fooReducer, 
     bar: barReducer 
    }) 
) 
]); 

Należy pamiętać, że spowoduje to zresetowanie wszystkich stanu sklepu - w tym router. Jeśli tego nie chcesz, możesz poprawić przykład.

z wprowadzeniem NgModule ładującego się nie zmieniło, ale nadal przechodzą skomponowaną reduktor do provideStore:

import { compose } from "@ngrx/core/compose"; 
import { StoreModule } from "@ngrx/store"; 

@NgModule({ 
    ... 
    imports: [ 
     ... 
     StoreModule.provideStore(compose(...)) 
    ], 
    ... 
+0

dzięki, działa idealnie! –

+0

Jak to zrobić w bieżącej wersji ngrx? – Daskus

+1

@ Daskus Przekazujesz skomponowany reduktor do 'StoreModule.provideStore'. Zobacz zaktualizowaną odpowiedź. – cartant

2

To naprawdę nie jest odpowiedzią, ale komentarze nie pozwoli mi go sformatować poprawnie. Aby dodać do tego, co powiedział właściciel, jeśli konfigurujesz swoje typy w ten sposób:

export const ActionTypes = { 
    LOGOUT: type('[Environment] Logout of portal'), 
    .... 
} 

To długi opis, którego powinieneś użyć. Także jeśli nazwiesz reduktor korzenia rootReducer zamiast tylko reducer, to też byś to zmienił. Poniżej znajduje się przykład edytowany:

(Zostawiłem tę funkcję w moim reduktora głównego)

const developmentReducer: ActionReducer<State> = compose(...DEV_REDUCERS, 
(rootReducer: Function) => { 
    return function(state, action) { 
     if (action.type === '[Environment] Logout of portal') { 
     state = undefined; 
     } 
     return rootReducer(state, action); 
    }; 
    }, combineReducers)(reducers); 
+0

Jak to zrobić z productionReducer? – misaizdaleka

12

W ngrx/sklepu 4.x, można to osiągnąć z metareducers. Jak rozumiem, wszystkie działania przechodzą przez mierniki, zanim zostaną przekazane do reduktorów funkcji. Daje nam to możliwość pierwszej zmiany/zresetowania stanu.

Oto przykład.

To jest moja funkcja miary: w przypadku akcji typu LOGOUT, stan jest ponownie inicjalizowany.

function logout(reducer) { 
    return function (state, action) { 
    return reducer(action.type === LOGOUT ? undefined : state, action); 
    } 
} 

Poniżej przedstawiono konfigurację miernika i reduktorów funkcji.Powinno być więcej niż 1 metareducer, a następnie wyceniane są od prawej do lewej

StoreModule.forRoot({rooms: roomReducer, user: userReducer}, {metaReducers: [logout]}) 

Wreszcie Mam też @effect gdzie przejdź do strony logowania

@Effect({dispatch: false}) logout: Observable<Action> = 
this.actions$.ofType(LOGOUT) 
    .do(() => { 
    // ... some more stuff here ... 
    this.router.navigate(['/login page']) 
}); 
+1

To powinna być akceptowana odpowiedź, ponieważ na razie 4.x ma pewne zmiany. – fubbe

4

Z @ ngrx/sklepu „:«^ 4.0.3»jest nieco inny, ponieważ istnieje niewielkie zmiany, więc moja«jasne stan»wygląda to

import { ActionReducerMap } from '@ngrx/store'; 
import { ActionReducer, MetaReducer } from '@ngrx/store'; 

export const rootReducer: ActionReducerMap<StoreStates> = { 
    points: pointsReducer, 
    ... 
}; 

export function clearState(reducer: ActionReducer<StoreStates>): ActionReducer<StoreStates> { 
    return function(state: StoreStates, action: Action): StoreStates { 
    if (action.type === 'CLEAR_STATE') { 
     state = undefined; 
    } 
    return reducer(state, action); 
    }; 
} 
export const metaReducers: MetaReducer<StoreStates>[] = [clearState]; 

i

import { StoreModule } from '@ngrx/store'; 
import { metaReducers, rootReducer } from '../root.reducer'; 

export const imports: any = [ 
    StoreModule.forRoot(rootReducer, { metaReducers }), 
    ... 
] 
+1

idealne dzięki! –

Powiązane problemy