在Angular 7中,可以使用Ngrx和Rxjs 6来实现在惰性加载模块之间访问状态。以下是一个解决方法的示例代码:
首先,安装必需的包:
npm install @ngrx/store@latest @ngrx/effects@latest --save
创建一个共享模块SharedModule:
shared.module.ts:
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
@NgModule({
imports: [
StoreModule.forRoot({}),
EffectsModule.forRoot([])
],
exports: [
StoreModule,
EffectsModule
]
})
export class SharedModule { }
在根模块AppModule中导入SharedModule:
app.module.ts:
import { NgModule } from '@angular/core';
import { SharedModule } from './shared/shared.module';
@NgModule({
imports: [
SharedModule
]
})
export class AppModule { }
创建一个状态模块StateModule:
state.module.ts:
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { featureReducer } from './state.reducer';
import { featureEffects } from './state.effects';
@NgModule({
imports: [
StoreModule.forFeature('feature', featureReducer),
EffectsModule.forFeature(featureEffects)
]
})
export class StateModule { }
在惰性加载的模块LazyModule中导入StateModule:
lazy.module.ts:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StateModule } from './state/state.module';
@NgModule({
imports: [
CommonModule,
StateModule
]
})
export class LazyModule { }
在状态模块StateModule中定义状态和效果:
state.reducer.ts:
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state.state';
import { action1, action2 } from './state.actions';
export const featureReducer = createReducer(
initialState,
on(action1, (state, { payload }) => ({ ...state, prop1: payload })),
on(action2, (state, { payload }) => ({ ...state, prop2: payload }))
);
state.actions.ts:
import { createAction, props } from '@ngrx/store';
export const action1 = createAction('[Feature] Action 1', props<{ payload: any }>());
export const action2 = createAction('[Feature] Action 2', props<{ payload: any }>());
state.effects.ts:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { map } from 'rxjs/operators';
import { action1, action2 } from './state.actions';
@Injectable()
export class FeatureEffects {
effect1$ = createEffect(() => this.actions$.pipe(
ofType(action1),
map(({ payload }) => action2({ payload: payload + ' transformed' }))
));
constructor(private actions$: Actions) { }
}
现在,在LazyModule中可以通过使用NgRx的select函数来访问状态:
lazy.component.ts:
import { Component } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';
import { prop1Selector } from './state/state.selectors';
@Component({
selector: 'app-lazy',
template: `
{{ prop1$ | async }}
`
})
export class LazyComponent {
prop1$: Observable;
constructor(private store: Store) {
this.prop1$ = this.store.pipe(select(prop1Selector));
}
dispatchAction() {
this.store.dispatch(action1({ payload: 'new value' }));
}
}
state.selectors.ts:
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { State } from './state.state';
export const selectFeatureState = createFeatureSelector('feature');
export const prop1Selector = createSelector(selectFeatureState, state => state.prop1);
现在,当在LazyModule中点击按钮时,将触发状态的更新,并相应地显示在LazyComponent中的{{ prop1$ | async }}中。