Angular 14中两个独立@NGRX Store间通信问题求助
解决Angular 14 + @NGRX 多独立Store间通信的方案
方法1:搭建全局共享Store作为数据桥梁
- 创建一个独立的
SharedStore,专门存储跨路由、跨组件的共享数据(比如你的拖拽目标值)。 - 拖拽组件所在的Store在更新值时,通过
@ngrx/effects触发共享Store的action,将值同步到共享Store中。 - 放置组件所在的Store通过选择器从共享Store查询数据,或直接在组件中注入共享Store获取值。
代码示例:
// 共享Store的action定义 export const updateDragValue = createAction( '[Shared] Update Drag Value', props<{ value: any }>() ); // 共享Store的状态与reducer export interface SharedState { dragValue: any; } const initialState: SharedState = { dragValue: null }; export function sharedReducer(state = initialState, action: Action): SharedState { switch (action.type) { case '[Shared] Update Drag Value': return { ...state, dragValue: (action as any).value }; default: return state; } } // 拖拽组件Store的effect,同步值到共享Store @Injectable() export class DragEffects { syncToSharedStore$ = createEffect(() => this.actions$.pipe( ofType('[Drag Store] Update Drag Value'), map(action => updateDragValue({ value: action.value })) ) ); constructor(private actions$: Actions) {} } // 放置组件中获取共享Store的值 @Component({ template: '' }) export class DropComponent { dragValue$ = this.sharedStore.select(state => state.dragValue); constructor(private sharedStore: Store<SharedState>) {} }
方法2:用RxJS Subject实现跨Store消息传递
- 在全局共享服务中创建
BehaviorSubject,作为拖拽值的传递通道。 - 拖拽组件所在的Store在值更新时,通过effect将值发送到这个Subject。
- 放置组件所在的Store通过effect订阅Subject,触发自身Store的action更新状态,或直接在组件中订阅获取值。
代码示例:
// 全局共享服务 @Injectable({ providedIn: 'root' }) export class DragDropBridgeService { private dragValue$ = new BehaviorSubject<any>(null); public readonly dragValueObservable$ = this.dragValue$.asObservable(); updateDragValue(value: any) { this.dragValue$.next(value); } } // 拖拽组件Store的effect @Injectable() export class DragEffects { notifyBridgeService$ = createEffect(() => this.actions$.pipe( ofType('[Drag Store] Update Drag Value'), tap(action => this.bridgeService.updateDragValue(action.value)) ), { dispatch: false } ); constructor(private actions$: Actions, private bridgeService: DragDropBridgeService) {} } // 放置组件Store的effect,同步值到自身Store @Injectable() export class DropEffects { syncDragValue$ = createEffect(() => this.bridgeService.dragValueObservable$.pipe( filter(value => value !== null), map(value => updateDropTarget({ value })) ) ); constructor(private bridgeService: DragDropBridgeService) {} }
方法3:借助浏览器本地存储实现跨页数据同步
- 拖拽组件所在的Store在值更新时,通过effect将值存入
localStorage或sessionStorage。 - 放置组件所在的Store通过effect监听存储变化事件,或在初始化时读取存储值,更新自身Store状态。
代码示例:
// 拖拽组件Store的effect @Injectable() export class DragEffects { saveToStorage$ = createEffect(() => this.actions$.pipe( ofType('[Drag Store] Update Drag Value'), tap(action => localStorage.setItem('dragTarget', JSON.stringify(action.value))) ), { dispatch: false } ); constructor(private actions$: Actions) {} } // 放置组件Store的effect @Injectable() export class DropEffects { loadFromStorageOnInit$ = createEffect(() => defer(() => of(localStorage.getItem('dragTarget'))).pipe( filter(val => val !== null), map(val => JSON.parse(val)), map(value => updateDropTarget({ value })) ) ); listenToStorageChanges$ = createEffect(() => fromEvent(window, 'storage').pipe( filter((e: StorageEvent) => e.key === 'dragTarget'), map(e => JSON.parse(e.newValue!)), map(value => updateDropTarget({ value })) ) ); constructor() {} }
内容的提问来源于stack exchange,提问作者K.G.K.Thilina
相关产品推荐
相关产品推荐

