Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 app module with root level imports

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?

like image 249
Werner Swart Avatar asked Aug 26 '16 06:08

Werner Swart


2 Answers

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.

like image 139
Post Impatica Avatar answered Oct 04 '22 06:10

Post Impatica


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).

like image 45
jbin Avatar answered Oct 04 '22 07:10

jbin