1

I have been reading over the seed template for Angular 2 projects and have a question about when to have a module vs components inside a larger module. I understand it it reccommended to create modules per feature but am having a hard time coming to a decision how to structure.

I have a project, where there is a public and admin section (admin is wrapped in a guard). Each section has a few different features, but they share the same underlying models (get an item, create an item, etc). My question is, what is the best way to structure this, knowing that some components need to be guarded? Do I have an AppModule with a Public and AdminModule (guarded) underneath it (with components that reference models in a sharedmodule) and a module for each feature under there? Or do I have an AppModule with all the Feature modules underneath and guard each component directly? I imagine this question is asked a lot, or I am asking in the wrong place, so any direction on where/what to do would be appreciated.

AppModule for reference

import { NgModule, Inject } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule, APP_BASE_HREF } from '@angular/common';
import { HttpModule, Http } from '@angular/http';
import { FormsModule } from '@angular/forms';
import { Ng2BootstrapModule } from 'ngx-bootstrap';
import { NavMenuComponent } from './navmenu/navmenu.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { LinkService } from '../shared/link.service';
import { AuthenticationService } from './authentication.service';
import { ORIGIN_URL } from '../shared/constants/baseurl.constants';
import { TransferHttpModule } from '../../modules/transfer-http/transfer-http.module';

@NgModule({
declarations: [
    NavMenuComponent,
    NotFoundComponent
],
imports: [
    CommonModule,
    HttpModule,
    FormsModule,
    RouterModule,
    Ng2BootstrapModule.forRoot(),
    TransferHttpModule,
],
providers: [
    LinkService,
    AuthenticationService,
],
exports: [
    CommonModule,
    HttpModule,
    FormsModule,
    Ng2BootstrapModule,
    TransferHttpModule,
    RouterModule
]
})
export class CoreModule {
}
Isaac Levin
  • 2,809
  • 9
  • 49
  • 88
  • Could you state exactly what you mean when you describe one module being "underneath" another? eg: you wrote "do I have an AppModule with all the Feature modules underneath and guard each component directly?" – BeetleJuice Jun 19 '17 at 04:21
  • Like an App module that imports all the other feature modules and I just put the components to guard at the top level route. – Isaac Levin Jun 19 '17 at 06:31
  • Ok I think I understand. Wrote up an answer. – BeetleJuice Jun 21 '17 at 03:49

1 Answers1

0

Initial Answer

Sounds like you will need:

  • A service module -- conventionally named CoreModule -- that has the services (providers) that will be used by the entire app. Eg: a custom AuthenticationService or HttpService. I would also export the Angular native services that should have application wide scope from here (eg: RouterModule, FormsModule). Your main AppModule will be the only one to import CoreModule

  • A widget module that has (and exports) the Components, Directives and Pipes shared across many components of the app: SharedModule might be a good name for it.

  • A very thin AppModule that basically has a single AppComponent with a router outlet (if your app has routing) and a bare template. The meat of the app would be displayed in <router-outlet> and controlled by the next 2 modules

  • A CustomerModule with the Components, Directives and Pipes needed exclusively to serve the app to end users (if you have a large app, this might be several modules). This module would import SharedModule. You will need the corresponding CustomerRoutingModule with router path-to-component instructions

  • An AdminModule with the Components, Directives and Pipes needed exclusively to serve the admin interface. you will need the corresponding AdminRoutingModule and its Guards with router instructions

Basically, the components that you need guarded should belong just to the Admin module. Take a look at this link from the docs for inspiration

Addendum

Errors about tags not existing occur because Ng2BootstrapModule is not properly imported into the module that throws errors. Import Ng2BootstrapModule (or a .forChild() if it exists) into SharedModule and import SharedModule into all your other modules. Or if you don't have a SharedModule, just import Ng2BootsrapModule (or a .forChild() if it exists) into each of your other modules (except CoreModule which already has Ng2BootsrapModule.forRoot()

Remember that CoreModule should be imported only into your root AppModule; not into other modules.

Community
  • 1
  • 1
BeetleJuice
  • 39,516
  • 19
  • 105
  • 165
  • Thanks for this. I like the idea you proposed, but was curious about something 3rd party in a CoreModule. I am using ngx-bootstrap, and when I move it to CoreModule, I get errors in the browser about some tags not existing. Is there a limitation to what I can put there. I have included my current App.Module for reference – Isaac Levin Jun 21 '17 at 05:05
  • I would import `Ng2BootstrapModule.forRoot()` directly into the root `AppModule`, and imort `Ng2BootstrapModule` (or a `.forChild()` if it exists) into a `SharedModule`, then re-export it. If you don't have a `SharedModule`, then import `Ng2BootstrapModule` into other modules directly. The problem with the code you posted is that you're trying to export `Ng2BootstrapModule` but that's not what you imported. – BeetleJuice Jun 21 '17 at 12:22
  • Actually, ignore the last sentence in my last comment. – BeetleJuice Jun 22 '17 at 01:59
  • So what should it look like? I am sorry but I am not quite following. Do you need to see more code? – Isaac Levin Jun 22 '17 at 14:53
  • I added a bit to my answer. – BeetleJuice Jun 22 '17 at 15:04
  • I am getting this now.. So Bootstrap can't live in CoreModule? – Isaac Levin Jun 22 '17 at 19:43
  • it can, but that doesn't automatically make it accessible from all other modules. If only the root module imports `CoreModule` (as should be the case) how will the other modules know about Bootstrap components unless they import it for themselves? – BeetleJuice Jun 23 '17 at 12:00