☰ See All Chapters |
Module in Angular - @NgModule
Angular class annotated with @NgModule help to organize an application into cohesive blocks of functionalities and extend it with capabilities from external libraries. Take for example, you have 10 components in your project, and that translates into 10 files. Now, given that you have another two new components – namely ComponentA and ComponentB. These 2 components depend on the 10 components we just described above.
Prior to RC 5, this is how you do it.
// a.component.ts // import all 10 components here import { No1Component, No2Component, ... } from './components';
@Component({ selector: 'a-cmp', templateUrl: 'a-cmp.component.html', directives: [No1Component, No2Component, ...] // inject all 10 components here }) export class AComponent { } |
Then, repeat the same process for ComponentB. Now, if we were to create many more components that behave like ComponentA and ComponentB, it surely will become cumbersome to keep including these 10 components into every other component. It is certainly not a fun thing to do! However, you create a grouped constant with all 10 components imported and then export this one constant to use by other components. Let’s look at a more refactored code:
// groupOfComponents.ts // import all 10 components here import { No1Component, No2Component, ... } from './components';
// export an array of all 10 components export const groupedComponents = [No1Component, No2Component, ...]; |
Then change your ComponentA code, to import the grouped constant to ComponentA
// a.component.ts import { groupedComponents } from './barrel';
@Component({ selector: 'a-cmp', templateUrl: 'a-cmp.component.html', directives: [groupedComponents] // inject all grouped components here }) export class AComponent { } |
The code is earlier to include components, but now you still have to include groupedComponents in every component that you need it. The solution for this is @NgModule. With @NgModule, what you need to do is this
// a.component.ts
@Component({ selector: 'a-cmp', templateUrl: 'a-cmp.component.html' // no more directives, no more importing component to component }) export class AComponent { } |
By declaring components, directives, pipes under @NgModule, You no need to import any components, directives, pipes to any of your components. All the components, directives, pipes declared under @NgModule will be available throughout the components under the module.
Every Angular app has at least one module, the root module, conventionally named AppModule.
Here is how a typical AppModule will look like:
// app.module.ts
@NgModule({ declarations: [ // put all your components / directives / pipes here AppComponent, // the root component No1Component, No2Component, ... // e.g. put all 10 components here AComponent, BComponent, // e.g. put component A and B here NiceDirective, AwesomePipe, ], imports: [ // put all your modules here BrowserModule, // Angular 2 out of the box modules TranslateModule, // some third party modules / libraries ], providers: [ // put all your services here AwesomeService, ], bootstrap: [ // The main components to be bootstrapped, normally one only AppComponent ] }) export class AppModule { } |
You should bootstrap your application using this app.module.ts.
// main.ts
... platformBrowserDynamic().bootstrapModule(AppModule); ... |
@NgModule fields
The @NgModule decorator has four fields:
Field | Description |
declarations | Declare the components, directives, and pipes contained in the application. |
imports | Declare the components required by the application |
providers | Declare the support classes contained in the application |
bootstrap | Declare the component that launches the application |
The difference between import statements and the imports array in @NgModule is every typescript file used by the current typescript file should be imported by import statement whereas imports array of @NgModule only contains the features required by the application. For the most part, these are provided by the Angular framework. At minimum, this array should contain BrowserModule.
The support classes like services, controllers which are not annotated with any angular annotations but just supporting classes should be declared under providers array. These supporting classes don't affect the user interface directly, but provide data and methods that can be accessed by components, directives, and other Angular classes.
The last array, bootstrap, identifies the application's primary component. This is the component that launches the application. In every application I've encountered, this array only contains one element. The bootstrapping process is made possible by the BrowserModule. BrowserModule is the angular provided class.
All Chapters