简体   繁体   中英

How to access another modules store with ngrx's StoreModule.forRoot() and StoreModule.forFeature()

Building an angular5 app... so many moving parts compared to vue or react, but i'm sticking with it.

Making use of angulars lazy loading of modules I am producing each page in angular as a module. Each module has its own encapsulated store using ngrx's:

StoreModule.forFeature('home', HomeReducer),

So far so good.. we can easily inject data into the HomePages store with the module looking a little like this:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';

import { HomeComponent } from './home.component';
import { HomeRoutingModule } from './home-routing.module';
import { HomeReducer } from '@modules/page/home/redux/home.reducers';
import { HomeEffects } from '@modules/page/home/redux/home.effects';
import { HomeService } from '@modules/page/home/home.service';

@NgModule({
  declarations: [
    HomeComponent
  ],
  imports: [
    CommonModule,
    HomeRoutingModule,
    StoreModule.forFeature('home', HomeReducer),
    EffectsModule.forFeature([HomeEffects])
  ],
  exports: [],
  providers: [
    HomeService
  ],
})

export class HomeModule {
}

The component is also quite simple and looks like this:

import { Component, OnInit } from '@angular/core';
import * as homeActions from './redux/home.actions';
import { Store } from '@ngrx/store';
import { HomeState } from '@modules/page/home/redux/home.state';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-home-component',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

  cars: Observable<any>;

  constructor (private store: Store<HomeState>) {
    this.cars = this.store.select(homeActions.getCars);
  }

  ngOnInit () {
  }

  clickme () {
    // dispatch a fetch to the store. gallery of images.
    // todo add a propper type model
    const imageType: any = {
      type: 'cars'
    };

    this.store.dispatch(new homeActions.GalleryFetch(imageType));
  }
}

The clickme function dispatches and action which is listened by the effects which in turns triggers another action on successful http request which finally places the data into the view...

But now the obvious next step.. i need to share this data with another page. Two questions immediately come to mind

1 - What is the best way to access one modules store data from another module?

2 - What is the point of encapsulating the module data like this if it needs to be shared with another module, eg a login module will always need to share the user data.. is the answer to only use this forFeature() for data that really will only be used by the module?

IMHO: Splitting state into modules is a nice ideology for the ultimate practice of reusable chunks of code. I mean to write a self contained module and simply drop it into your app is great... but an app will nearly always need to pass data from one module to the next, and when this needs to happen broken state into modules creates more issues than it solves.

You just need to import the HomeModule into another module, so in that way the home feature's store and effects will be registered in that new module as well. After that, you need to define the home feature's store in the constructor of the new module's component and you will be able to use it as you do in the HomeModule .

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