Angular2 app module with root level imports
Asked Answered
G

2

17

Shouldn't imports on the root level be available globally (With globally I mean to all sub-modules and components)?

I have the following root/app module :

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ApplicationRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { appRouterProviders, routing } from './app.routes';
import { DashboardModule } from './dashboard/dashboard.module';
import { DecisionModule } from './decision/decision.module';
import { MdCoreModule }           from '@angular2-material/core';
import { MdButtonModule }         from '@angular2-material/button';
import { MdCardModule }           from '@angular2-material/card';
import { MdListModule }           from '@angular2-material/list';
import { MdSidenavModule }        from '@angular2-material/sidenav';
import { MdToolbarModule }        from '@angular2-material/toolbar';
import { MdIconModule }           from '@angular2-material/icon';

@NgModule({
  declarations: [
    AppComponent                    
  ],
  imports: [
    BrowserModule,
    CommonModule,
    FormsModule,
    HttpModule,
    RouterModule,    
    routing,
    DashboardModule,
    MdCoreModule,
    MdButtonModule,
    MdCardModule,
    MdListModule,
    MdSidenavModule,    
    MdToolbarModule,
    MdIconModule
  ],
  providers: [
    appRouterProviders
  ],
  entryComponents: [ AppComponent ],
  bootstrap: [ AppComponent ]
})
export class AppModule {

}

If I try to use the material elements in one of my sub modules they don't display, this is what the sub module looks like:

import { NgModule }               from '@angular/core';
import { CommonModule }           from '@angular/common';
import { FormsModule }            from '@angular/forms';
import { dashboardRouting }       from './dashboard.routes';
import { DashboardComponent }     from './dashboard.component';
import { ActionsDialogComponent } from './actions-dialog';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    dashboardRouting,    
  ],
  declarations: [
    DashboardComponent,
    ActionsDialogComponent    
  ],
  providers: [    
  ]
})
export class DashboardModule {}

However if I import the material modules in the submodule they display. This is what the submodule looks like when the material design components work:

import { NgModule }               from '@angular/core';
import { CommonModule }           from '@angular/common';
import { FormsModule }            from '@angular/forms';
import { dashboardRouting }       from './dashboard.routes';
import { DashboardComponent }     from './dashboard.component';
import { ActionsDialogComponent } from './actions-dialog';
import { MdCoreModule }           from '@angular2-material/core';
import { MdButtonModule }         from '@angular2-material/button';
import { MdCardModule }           from '@angular2-material/card';
import { MdListModule }           from '@angular2-material/list';
import { MdSidenavModule }        from '@angular2-material/sidenav';
import { MdToolbarModule }        from '@angular2-material/toolbar';
import { MdIconModule }           from '@angular2-material/icon';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    dashboardRouting,
    MdCoreModule,
    MdButtonModule,
    MdCardModule,
    MdListModule,
    MdSidenavModule,    
    MdToolbarModule,
    MdIconModule,
  ],
  declarations: [
    DashboardComponent,
    ActionsDialogComponent    
  ],
  providers: [    
  ]
})
export class DashboardModule {}

Why must the material modules be imported on the sublevel again if they are already imported at the root level?

Gherkin answered 26/8, 2016 at 6:37 Comment(2)
Your modules should be reusable. Why would anyone using your module be required to import all kinds of modules to his root module? That only makes your modules harder to re-use.Leighleigha
O wait...that's true. Thanks.Gherkin
U
9

In the concept of Components in Angular2 there is nothing like a "root level" to which you are referring.
Components are modular pieces very much like Classes in a Java (or whatever High level language) project - where you would also import every Class you use.
They can be nested or used inside each other, but still every components needs to import its own dependencies.
Please note that importing in Angular2 is a very different approach than including a external module/library was in Angular 1 (then essentially beeing a new reference in index.html for each dependency).
Those imports in Angular 2 are there first, because the Typescript-compiler needs to know what is used in your component (thus adding some more power to do error checking)
The compiled and packaged build should include every dependency just once (provided everything is configured correctly).

Undergarment answered 26/8, 2016 at 6:51 Comment(0)
G
51

Angular's documentation is confusing, they state in several areas that modules you import in the root module(app.module.ts) are available globally, but what is not quickly evident unless you read thoroughly (blah) is that when you use a submodule it breaks that inheritance and a submodule creates it's own app domain for components (not services, services are still global, at least the way I read it). That's also why if you were like me, I noticed some items I had to import into my sub-module, and others I didn't which really confused me. Here's the section on angular.io that discusses this: NgModule.html

Something else worth mentioning: I thought developing in Angular2 since RC5+ meant that I needed to wrap all my features up into modules, this is simply not the case. Modules aren't really necessary for us to build in our general day to day work with Angular2 unless you want to use lazy loading or are specifically desiring to share code with others, for example an npm package.

Geanticline answered 27/8, 2016 at 21:56 Comment(4)
"I noticed some items I had to import into my sub-module, and others I didn't which really confused me." - broke my brain with this for a long time. Good explanation.Argumentum
mind blown puufffffff. this saved me a headache while trying to use angular material modules. thanks!Tutor
Thanks for the explanation. I have stuck on this for several days. It worked after I move declaration from global to the module level.Laden
This just helped me on an Angular 10 build in 2022. Thank you much.Detonate
U
9

In the concept of Components in Angular2 there is nothing like a "root level" to which you are referring.
Components are modular pieces very much like Classes in a Java (or whatever High level language) project - where you would also import every Class you use.
They can be nested or used inside each other, but still every components needs to import its own dependencies.
Please note that importing in Angular2 is a very different approach than including a external module/library was in Angular 1 (then essentially beeing a new reference in index.html for each dependency).
Those imports in Angular 2 are there first, because the Typescript-compiler needs to know what is used in your component (thus adding some more power to do error checking)
The compiled and packaged build should include every dependency just once (provided everything is configured correctly).

Undergarment answered 26/8, 2016 at 6:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.