如何重置ngrx / store的所有状态?

时间:2016-09-05 02:47:18

标签: angular typescript ngrx

我正在使用Angular 2和1。我想在用户发送USER_LOGOUT时重置整个商店状态。

我读了Dan Abramov对ngrx/store的回答,但我没有弄清楚如何正确地写rootReducer以及在使用ngrx / store时把它放在哪里。

或者还有其他方法可以在ngrx / store中处理这个吗?

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

4 个答案:

答案 0 :(得分:32)

在ngrx / store 4.x中,可以使用metareducers完成此操作。据我了解,所有操作都会在传递给功能减少器之前通过元数据删除器。这使我们有机会首先更改/重置状态。

以下是一个例子。

这是我的metareducer函数:如果操作是LOGOUT类型,则重新初始化状态。

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

下面您将看到如何配置metareducer以及功能缩减器。如果有超过1个metareducer,那么它们将从右到左进行评估

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

最后,我还有一个@effect导航到登录页面

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

答案 1 :(得分:14)

此答案特定于ngrx版本2.问题为another, more recent answer,解释了如何使用ngrx版本4完成相同的操作。

<!--------------------------- EXTERNAL BOILER PLATE STUFF -----------------------------> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script><link rel="stylesheet" type="text/css" href="/css/result-light.css"><link rel="stylesheet" type="text/css" href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css"><link rel="stylesheet" type="text/css" href="http://getbootstrap.com/2.3.2/assets/css/bootstrap-responsive.css"><link rel="stylesheet" type="text/css" href="http://jschr.github.io/bootstrap-modal/css/bootstrap-modal.css"><script type="text/javascript" src="http://getbootstrap.com/2.3.2/assets/js/bootstrap.js"></script><script type="text/javascript" src="http://jschr.github.io/bootstrap-modal/js/bootstrap-modalmanager.js"></script><script type="text/javascript" src="http://jschr.github.io/bootstrap-modal/js/bootstrap-modal.js"></script> <a id="newBtn" href="#" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">New</a> <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&#215;</span></button> <h4 class="modal-title" id="exampleModalLabel">Input parameters</h4> </div> <div class="modal-body"> <form> <div class="form-group"> <label for="url-base" class="form-control-label">Base URL (optional):</label> <input type="text" class="form-control" id="url-base" placeholder="Example: https://www.merkel.com/obama?trump=15&amp;id=9616071454&amp;hilarry=es"> </div> <div class="form-group"> <label for="max-pics" class="form-control-label">Max #pics:</label> <input type="text" class="form-control" id="max-pics" placeholder="Default: 7"> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button id="paramsOkay" type="button" class="btn btn-primary">Okay</button> </div> </div> </div> </div>构建ngrx 根减速器

传递给compose的参数是返回reducer的函数 - 由reducer组成,它们本身作为参数传递。您可以像这样构建商店的重置:

compose

请注意,这会重置所有商店的状态 - 包括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 }) ) ]); 。如果那不是你想要的,你可以调整一下这个例子。

引入router引导已更改,但您仍然将组合的reducer传递给NgModule

provideStore

答案 2 :(得分:13)

使用@ ngrx / store&#34;:&#34; ^ 4.0.3&#34;这略有不同,因为有一些小的变化,所以我的状态很明显&#39;看起来像这样

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];

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

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

答案 3 :(得分:2)

这不是一个真正的答案,但评论不会让我正确格式化。要添加到cartant所说的内容,如果您要设置类似的类型:

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

这是你应该使用的长篇描述。此外,如果您将根缩减器rootReducer命名为reducer而不仅仅是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); ,那么您也可以更改它。以下是一个经过编辑的例子:

(我在root减速器中保留了这个功能)

static public charchar box1 = ' ', box2 = ' ', box3 = ' ', box4 = ' ', box5 = ' ', box6 = ' ', box7 = ' ', box8 = ' ', box9 = ' ', input2;

static public void reset()
{
    char box1 = ' ', box2 = ' ', box3 = ' ', box4 = ' ', box5 = ' ', box6 = ' ', box7 = ' ', box8 = ' ', box9 = ' ', input2;
    bool isWin = false;
    int line = 1, nrJogada = 1;
    ciclo();
}