首页 > 解决方案 > 在页面加载时,Ngrx Store 会丢失当前状态;如何在页面加载时检索现有状态?

问题描述

设想:

我目前在带有 NgRx 的 Angular 应用程序中使用外观设计模式。在我加载或刷新页面的那一刻,我正在失去商店的现有状态。

我想在页面加载时检索现有状态。对于外观设计模式,如何在本地存储中存储状态以及检索状态并使用它有点令人困惑。

动作.ts

import { Action } from '@ngrx/store';

import { Login } from '../../models/auth';

export enum AuthActionTypes {
  Login = '[Login] InvokeLogin',
  LoginSuccess = '[Login] LoginSuccess',
  LoginFailure = '[Login] LoginFailure',

}

export class AuthAction implements Action {
  readonly type: string;
  loginData?: Login;

  loginSuccessData?: any;
  message?: string;
}


export class InvokeLoginAction implements AuthAction {
  readonly type = AuthActionTypes.Login;

  constructor(public loginData: Login) { }
}

export class LoginSuccessResponseAction implements AuthAction {
  readonly type = AuthActionTypes.LoginSuccess;

  constructor(public loginSuccessData: ProfileData) { }
}

export class LoginFailureResponseAction implements AuthAction {
  readonly type = AuthActionTypes.LoginFailure;

  constructor(public message: string) { }
}
export type AuthActions =
  InvokeLoginAction |
  LoginSuccessResponseAction |
  LoginFailureResponseAction

减速器.ts

import { AuthActions, AuthActionTypes } from '../actions/auth.actions';

export interface AuthState {
    isAuthenticated: boolean;
    errorMessage: string;
    successMessage: string;
}

export const initialState: AuthState = {
    isAuthenticated: false,
    errorMessage: '',
    successMessage: ''
};

export function AuthReducer(state: AuthState = initialState, action: AuthActions): AuthState {
    switch (action.type) {
            case AuthActionTypes.LoginSuccess: {
            state = {
                ...state,
                userProfile: action.loginSuccessData,
                isAuthenticated: true,
                errorMessage: ''
            };
            break;
        }
        case AuthActionTypes.LoginFailure: {
            state = {
                ...state,
                errorMessage: action.message
            };
            break;
        }
    
    }

    return state;
}

选择器.ts

import { createFeatureSelector, createSelector } from '@ngrx/store';
import { ProfileData } from '../../models/auth';

import { AuthState } from '../reducers/auth.reducer';

const AUTH_KEY = 'authentication';

const authFeature = createFeatureSelector<AuthState>(AUTH_KEY);

const isAuthenticated = createSelector(authFeature, (state: AuthState) => state.isAuthenticated);
const signUpSuccess = createSelector(authFeature, (state: AuthState) => state.successMessage);
const userProfile = createSelector(authFeature, (state: AuthState) => state.userProfile);

const errorMessage = createSelector(authFeature, (state: AuthState) => state.errorMessage);

export const authQuery = {
  isAuthenticated,
  errorMessage,
  userProfile
};

门面.ts

import { Injectable } from '@angular/core';
import { Store, select } from '@ngrx/store';

import { authQuery } from '../selectors/auth.selectors';
import { AuthState } from '../reducers/auth.reducer';
import {
  LoginSuccessResponseAction, LoginFailureResponseAction
} from '../actions/auth.actions';
import { ProfileData } from '../../models/auth';

@Injectable({
  providedIn: 'root'
})
export class AuthFacade {
  isAuthenticated$ = this.store.pipe(select(authQuery.isAuthenticated));
  userProfile$ = this.store.pipe(select(authQuery.userProfile));
  errorMessage$ = this.store.pipe(select(authQuery.errorMessage));


  constructor(private store: Store<AuthState>) { }

  onLoginSuccess(loginData: ProfileData) {
    this.store.dispatch(new LoginSuccessResponseAction(loginData));
  }

  onLoginFailure(errorMessage: string) {
    this.store.dispatch(new LoginFailureResponseAction(errorMessage));
  }

  resetErrorMessage() {
    this.store.dispatch(new LoginFailureResponseAction(''));
  }
}

reducer.mapper.ts

import { ActionReducerMap } from '@ngrx/store';
import { AuthReducer } from './reducers/auth.reducer';

export const reducerMapper: ActionReducerMap<any> = {
    authentication: AuthReducer,
};

app.module.ts

  imports: [
    BrowserAnimationsModule,
    FormsModule,
    ReactiveFormsModule,
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    StoreModule.forRoot(reducerMapper,{metaReducers}),
    StoreDevtoolsModule.instrument({
      maxAge: 25, // Retains last 25 states
      logOnly: environment.production, // Restrict extension to log-only mode
    })


   ],
  providers: [],
  bootstrap: [AppComponent],
})

标签: angulartypescriptangular8ngrxngrx-store

解决方案


推荐阅读