繁体   English   中英

Angular + ngrx:如何在路由器url遍历上保持存储状态?

[英]Angular+ngrx: how to keep store state on router url traversing?

我知道每次用户刷新页面时都会重置存储(所谓的“硬刷新”),但是当用户使用角度路由器遍历页面时,我希望它保持不变。 但是,正如我所看到的,它无论如何都会重置。

我错了吗? 有没有办法保存商店而不保存到LocalStorage或使用其他黑客?

app.module.ts

    import { NgModule } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { HttpClientModule } from '@angular/common/http';
    import { BrowserModule } from '@angular/platform-browser';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

    // Routing
    import { AppRoutingModule } from './app-routing.module';

    // Ngrx
    import { StoreModule } from '@ngrx/store';
    import {
      StoreRouterConnectingModule,
      RouterStateSerializer,
    } from '@ngrx/router-store';
    import { StoreDevtoolsModule } from '@ngrx/store-devtools';
    import { EffectsModule } from '@ngrx/effects';

    // Other
    import { reducers, metaReducers } from './core/reducers';
    import { CustomRouterStateSerializer } from './core/utils/router.utils';
    import { MaterialModule } from './material/material.module';

    // Environment
    import { environment } from '../environments/environment';

    // Components
    import { AppComponent } from './app.component';
    import { NotFoundComponent } from './core/components/not-found.component';
    import { NotAuthorizedComponent } from './core/components/not-authorized.component';
    import { HomeComponent } from './core/components/home.component';
    import { UsersModule } from './users/users.module';
    import { EventsModule } from "./events/events.module";

    @NgModule({
      declarations: [
        AppComponent,
        NotFoundComponent,
        HomeComponent,
        NotAuthorizedComponent,
      ],
      imports: [
        CommonModule,
        HttpClientModule,
        BrowserModule,
        BrowserAnimationsModule,
        AppRoutingModule,
        MaterialModule,
        StoreModule.forRoot(reducers, { metaReducers }), 
        StoreRouterConnectingModule.forRoot({stateKey: 'router'}),
        StoreDevtoolsModule.instrument(),
        EffectsModule.forRoot([]),
        UsersModule,
        EventsModule

  ],
  providers: [
    { provide: RouterStateSerializer, useClass: CustomRouterStateSerializer },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

./core/reducers/index.ts

import {
  ActionReducerMap,
  ActionReducer,
  MetaReducer, createFeatureSelector, createSelector,
} from '@ngrx/store';
import { environment } from '../../../environments/environment';
import { RouterStateUrl } from '../utils/router.utils';
import * as fromRouter from '@ngrx/router-store';
import * as fromAuth from '../../users/reducers/auth.reducer';

import { storeFreeze } from 'ngrx-store-freeze';

export interface State {
  router: fromRouter.RouterReducerState<RouterStateUrl>,
  auth: fromAuth.State;
}

export const reducers: ActionReducerMap<State> = {
  router: fromRouter.routerReducer,
  auth: fromAuth.reducer
};

export function logger(reducer: ActionReducer<State>): ActionReducer<State> {
  return function(state: State, action: any): State {
    console.log('state', state);
    console.log('action', action);

    return reducer(state, action);
  };
}

export const metaReducers: MetaReducer<State>[] = !environment.production
  ? [logger, storeFreeze]
  : [];

// AUTH reducers
export const selectAuthState = createFeatureSelector<fromAuth.State>('auth');

export const getUser = createSelector(
  selectAuthState,
  fromAuth.getUser
);
export const getLoaded = createSelector(
  selectAuthState,
  fromAuth.getLoaded
);
export const getError = createSelector(
  selectAuthState,
  fromAuth.getError
);

我们的想法是通过HTTP GET从服务器获取用户凭据,将它们存储在商店中,然后从商店而不是服务器获取它们。 所以我有一个警卫:

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private store: Store<State>, protected router: Router) {
  }

  protected getFromStoreOrAPI(): Observable<any> {
    return this.store
      .select(getUser)
      .do(user => {
        if (!user) this.store.dispatch(new Signin());
      })
      .filter(user => user)
      .take(1);
  }

  canActivate(): Observable<boolean> {
    return this.getFromStoreOrAPI()
      .switchMap(() => Observable.of(true))
      .catch(() =>  Observable.of(false));
  }
}

on this.store.dispatch(new Signin()); 它进行HTTP调用并将数据存储到存储中。

问题是,每次用户进入新页面时都会进行HTTP调用。

我这么傻! 使用<a href="/link">Link</a>而不是<a routerLink="/link">Link</a>

检查你的Reducer,我确定你忘记了在switch语句中返回状态:

switch(action.type){
       ...
        default:
            return state;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM