简体   繁体   中英

One NGRX store, multiple Angular Applications

So I'm a little bit nob with this. Hope you can apologise me.

I'm trying to insert multiple Angular elements (web components) into a Prestashop module, which is PHP. As there is not a single Angular App with many modules, I cannot use the store to send data from an element to another.

I have thought of creating a library which is in charge of creating the NGRX store, and kind of saves it to window.store (for instance), so the same store can be used by multiple independent angular apps. The issue here is that I have to invoke the library in many Angular elements, so I'm injecting different stores in the constructor. Am I right?

For instance:

import {
  ActionReducer,
  ActionReducerFactory,
  ActionReducerMap,
  ActionReducerMap,
  ActionsSubject,
  ReducerManager,
  ReducerManagerDispatcher,
  StateObservable,
  Store,
} from '@ngrx/store'
import { Observable } from 'rxjs';

const storeName = 'store'

@Injectable({
  providedIn: 'root'
})
export class StoreSyncService {

  store: any = null

  // option 1 constructor:
  // are we, when including the library in others angular apps, instantiating store over and over?
  constructor(private store: Store) {
     if (window[storeName]) {
      this.store = window[storeName]
    } else{
      window[storeName] = this.store
    }
  }

  // option 2 constructor (please apologise me as I don't know how injection works very well).
  // Any link to clarify this is welcome
  constructor() {
    if (window[storeName]) {
      this.store = window[storeName]
    } else{
      const stateObservable$: StateObservable = new Observable()
      const actionsObserver: ActionsSubject = new ActionsSubject()

      const dispatcher: ReducerManagerDispatcher = new ActionsSubject()
      const initialState = {}
      const reducers: ActionReducerMap<any, any> = {}
      const reducerFactory: ActionReducerFactory<any, any> =  whatever

      const reducerManager: ReducerManager = new ReducerManager(dispatcher, initialState, reducers, reducerFactory)
      this.store = new Store(stateObservable$, actionsObserver, reducerManager)
      window[storeName] = this.store
    }
  }

  public getStore = () => this.store

  public addReducer = (reducerName: string, reducer: ActionReducer<any>) => this.store.addReducer(reducerName, reducer)

  public removeReducer = (reducerName: string) => this.store.removeReducer(reducerName)

}

So to recap, if I want to share state between more than one independent angular app, how would you do?

I tried with localStorage, adding events to synchronize NGRX state with data in local storage and viceversa, but resulted, some times in a infinite loop and sometimes in edge cases in which data was not sync.

Thanks for your help and comprehension

So for now, I kind of found a workaround to avoid the double instantiation of the store. Using a conditional injector.

  import { Injectable, Injector } from '@angular/core';

  ...


  constructor(private injector : Injector) {
    if (window[storeName]) {
      this.store = window[storeName]
    } else{
      this.store = this.injector.get<Store>(Store);
      window[storeName] = this.store
    }
  }

I still haven't tested it to share data between the independent applications. Let's hope it works.

Any advice is always welcomed!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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