| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | # NgModules
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | **NgModules** help organize an application into cohesive blocks of functionality. | 
					
						
							|  |  |  | <!-- CF: "app" and "application" are used interchangeably throughout this page.
 | 
					
						
							|  |  |  | I'm not sure what's appropriate, so I left them as is for now.  --> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | An NgModule is a class adorned with the *@NgModule* decorator function. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | `@NgModule` takes a metadata object that tells Angular how to compile and run module code. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | It identifies the module's own components, directives, and pipes, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | making some of them public so external components can use them. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | `@NgModule` may add service providers to the application dependency injectors. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | And there are many more options covered here. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Before reading this page, read the | 
					
						
							| 
									
										
										
										
											2017-06-09 17:48:53 -04:00
										 |  |  | [The Root Module](guide/bootstrapping) page, which introduces NgModules and the essentials | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | of creating and maintaining a single root `AppModule` for the entire application. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This page covers NgModules in greater depth. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-04 18:46:43 +02:00
										 |  |  | <!-- CF: See my comment in the "Resolve directive conflicts" section below proposing renaming or reorganizing that section.
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | * [Angular modularity](guide/ngmodule#angular-modularity "Add structure to the app with NgModule") | 
					
						
							|  |  |  | * [The application root module](guide/ngmodule#root-module "The startup module that every app requires") | 
					
						
							| 
									
										
										
										
											2017-04-27 15:32:46 -07:00
										 |  |  | * [Bootstrap the root module](guide/ngmodule#bootstrap "Launch the app in a browser with the root module as the entry point") | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | * [Declarations](guide/ngmodule#declarations "Declare the components, directives, and pipes that belong to a module") | 
					
						
							|  |  |  | * [Providers](guide/ngmodule#providers "Extend the app with additional services") | 
					
						
							|  |  |  | * [Imports](guide/ngmodule#imports "Import components, directives, and pipes for use in component templates") | 
					
						
							|  |  |  | * [Resolve conflicts](guide/ngmodule#resolve-conflicts "When two directives have the same selector") | 
					
						
							|  |  |  | * [Feature modules](guide/ngmodule#feature-modules "Partition the app into feature modules") | 
					
						
							| 
									
										
										
										
											2017-04-27 15:32:46 -07:00
										 |  |  | * [Lazy loaded modules with the router](guide/ngmodule#lazy-load "Load modules asynchronously") | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | * [Shared modules](guide/ngmodule#shared-module "Create modules for commonly used components, directives, and pipes") | 
					
						
							|  |  |  | * [The Core module](guide/ngmodule#core-module "Create a core module with app-wide singleton services and single-use components") | 
					
						
							|  |  |  | * [Configure core services with _forRoot_](guide/ngmodule#core-for-root "Configure providers during module import") | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | * [Prevent reimport of the _CoreModule_](guide/ngmodule#prevent-reimport "because bad things happen if a lazy loaded module imports Core") | 
					
						
							|  |  |  | <!--
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | * [NgModule metadata properties](guide/ngmodule#ngmodule-properties "A technical summary of the @NgModule metadata properties") | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  |  CF: This link goes to the top of this page. I would expect it to go to an "NgModule metadata properties" | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |  section at the end of this page, but that section doesn't exist. --> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | #### Live examples
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This page explains NgModules through a progression of improvements to a sample with a "Tour of Heroes" theme. | 
					
						
							|  |  |  | Here's an index to live examples at key moments in the evolution of the sample: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | * <live-example plnkr="minimal.0">A minimal NgModule app</live-example> | 
					
						
							|  |  |  | * <live-example plnkr="contact.1b">The first contact module</live-example> | 
					
						
							|  |  |  | * <live-example plnkr="contact.2">The revised contact module</live-example> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | * <live-example plnkr="pre-shared.3">Just before adding SharedModule</live-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | * <live-example>The final version</live-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | #### Frequently asked questions (FAQs)
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This page covers NgModule concepts in a tutorial fashion. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | The companion [NgModule FAQs](guide/ngmodule-faq "NgModule FAQs") guide | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | offers answers to specific design and implementation questions. | 
					
						
							|  |  |  | Read this page before reading those FAQs. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <hr/> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a angular-modularity} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | ## Angular modularity
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Modules are a great way to organize an application and extend it with capabilities from external libraries. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Many Angular libraries are modules (such as `FormsModule`, `HttpModule`, and `RouterModule`). | 
					
						
							|  |  |  | Many third-party libraries are available as NgModules (such as | 
					
						
							| 
									
										
										
										
											2017-04-24 20:23:45 +02:00
										 |  |  | <a href="https://material.angular.io/">Material Design</a>, | 
					
						
							|  |  |  | <a href="http://ionicframework.com/">Ionic</a>, | 
					
						
							|  |  |  | <a href="https://github.com/angular/angularfire2">AngularFire2</a>). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | NgModules consolidate components, directives, and pipes into | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | cohesive blocks of functionality, each focused on a | 
					
						
							|  |  |  | feature area, application business domain, workflow, or common collection of utilities. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Modules can also add services to the application. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Such services might be internally developed, such as the application logger. | 
					
						
							|  |  |  | Services can come from outside sources, such as the Angular router and Http client. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Modules can be loaded eagerly when the application starts. | 
					
						
							|  |  |  | They can also be _lazy loaded_ asynchronously by the router. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | An NgModule is a class decorated with `@NgModule` metadata. The metadata do the following: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * Declare which components, directives, and pipes belong to the module. | 
					
						
							|  |  |  | * Make some of those classes public so that other component templates can use them. | 
					
						
							|  |  |  | * Import other modules with the components, directives, and pipes needed by the components in _this_ module. | 
					
						
							|  |  |  | * Provide services at the application level that any application component can use. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Every Angular app has at least one module class, the _root module_. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You bootstrap that module to launch the application. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The root module is all you need in a simple application with a few components. | 
					
						
							|  |  |  | As the app grows, you refactor the root module into *feature modules* | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that represent collections of related functionality. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You then import these modules into the root module. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Later in this page, you'll read about this process. For now, you'll start with the root module. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a root-module} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | ## The root _AppModule_
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Every Angular app has a *root module* class. | 
					
						
							|  |  |  | By convention, the *root module* class is called `AppModule` and it exists in a file named `app.module.ts`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | The `AppModule` from the QuickStart seed on the [Setup](guide/setup) page is as minimal as possible: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="setup/src/app/app.module.ts" title="src/app/app.module.ts (minimal)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `@NgModule` decorator defines the metadata for the module. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This page takes an intuitive approach to understanding the metadata and fills in details as it progresses. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The metadata imports a single helper module, `BrowserModule`, which every browser app must import. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | `BrowserModule` registers critical application service providers. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | It also includes common directives like `NgIf` and `NgFor`, which become immediately visible and usable | 
					
						
							|  |  |  | in any of this module's component templates. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `declarations` list identifies the application's only component, | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | the _root component_, the top of the app's rather bare component tree. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The example `AppComponent` simply displays a data-bound title: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.component.0.ts" title="src/app/app.component.ts (minimal)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Lastly, the `@NgModule.bootstrap` property identifies this `AppComponent` as the _bootstrap component_. | 
					
						
							|  |  |  | When Angular launches the app, it places the HTML rendering of `AppComponent` in the DOM, | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | inside the `<my-app>` element tags of the `index.html`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a bootstrap} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Bootstrapping in _main.ts_
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You launch the application by bootstrapping the `AppModule` in the `main.ts` file. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Angular offers a variety of bootstrapping options targeting multiple platforms. | 
					
						
							|  |  |  | This page describes two options, both targeting the browser. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | ### Compile just-in-time (JIT)
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | In the first, _dynamic_ option, the [Angular compiler](guide/ngmodule-faq#q-angular-compiler "About the Angular Compiler") | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | compiles the application in the browser and then launches the app. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/main.ts" title="src/main.ts (dynamic)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The samples in this page demonstrate the dynamic bootstrapping approach. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:12:22 +03:00
										 |  |  | <live-example embedded plnkr="minimal.0" img="guide/ngmodule/minimal-plunker.png">Try the live example.</live-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | ### Compile ahead-of-time (AOT)
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Consider the static alternative which can produce a much smaller application that | 
					
						
							|  |  |  | launches faster, especially on mobile devices and high latency networks. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | In the _static_ option, the Angular compiler runs ahead of time as part of the build process, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | producing a collection of class factories in their own files. | 
					
						
							|  |  |  | Among them is the `AppModuleNgFactory`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The syntax for bootstrapping the pre-compiled `AppModuleNgFactory` is similar to | 
					
						
							|  |  |  | the dynamic version that bootstraps the `AppModule` class. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/main-static.ts" title="src/main.ts (static)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Because the entire application was pre-compiled, | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Angular doesn't ship the Angular compiler to the browser and doesn't compile in the browser. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The application code downloaded to the browser is much smaller than the dynamic equivalent | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | and it's ready to execute immediately. The performance boost can be significant. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Both the JIT and AOT compilers generate an `AppModuleNgFactory` class from the same `AppModule` | 
					
						
							|  |  |  |  source code. | 
					
						
							|  |  |  | The JIT compiler creates that factory class on the fly, in memory, in the browser. | 
					
						
							|  |  |  | The AOT compiler outputs the factory to a physical file | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | that is imported here in the static version of `main.ts`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | In general, the `AppModule` should neither know nor care how it is bootstrapped. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Although the `AppModule` evolves as the app grows, the bootstrap code in `main.ts` doesn't change. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This is the last time you'll look at `main.ts`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <hr/> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a declarations} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Declare directives and components
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | As the app evolves, | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | the first addition is a `HighlightDirective`, an [attribute directive](guide/attribute-directives) | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that sets the background color of the attached element. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/highlight.directive.ts" title="src/app/highlight.directive.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Update the `AppComponent` template to attach the directive to the title: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.component.1.ts" region="template" title="src/app/app.component.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | If you ran the app now, Angular wouldn't recognize the `highlight` attribute and would ignore it. | 
					
						
							|  |  |  | You must declare the directive in `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Import the `HighlightDirective` class and add it to the module's `declarations` like this: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.1.ts" region="directive" title="src/app/app.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Refactor the title into its own `TitleComponent`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The component's template binds to the component's `title` and `subtitle` properties like this: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/title.component.html" region="v1" title="src/app/title.component.html" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/title.component.ts" region="v1" title="src/app/title.component.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Rewrite the `AppComponent` to display the new `TitleComponent` in the `<app-title>` element, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | using an input binding to set the `subtitle`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.component.1.ts" title="src/app/app.component.ts (v1)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Angular won't recognize the `<app-title>` tag until you declare it in `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Import the `TitleComponent` class and add it to the module's `declarations`: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.1.ts" region="component" title="src/app/app.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a providers} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | ## Service providers
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Modules are a great way to provide services for all of the module's components. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | The [Dependency Injection](guide/dependency-injection) page describes | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | the Angular hierarchical dependency-injection system and how to configure that system | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | with [providers](guide/dependency-injection#providers) at different levels of the | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | application's component tree. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A module can add providers to the application's root dependency injector, making those services | 
					
						
							|  |  |  | available everywhere in the application. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Many applications capture information about the currently logged-in user and make that information | 
					
						
							|  |  |  | accessible through a user service. | 
					
						
							|  |  |  | This sample application has a dummy implementation of such a `UserService`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/user.service.ts" title="src/app/user.service.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The sample application should display a welcome message to the logged-in user just below the application title. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Update the `TitleComponent` template to show the welcome message below the application title. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/title.component.html" title="src/app/title.component.html" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Update the `TitleComponent` class with a constructor that injects the `UserService` | 
					
						
							|  |  |  | and sets the component's `user` property from the service. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/title.component.ts" title="src/app/title.component.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You've defined and used the service. Now to _provide_ it for all components to use, | 
					
						
							|  |  |  | add it to a `providers` property in the `AppModule` metadata: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.1.ts" region="providers" title="src/app/app.module.ts (providers)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a imports} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Import supporting modules
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | In the revised `TitleComponent`, an `*ngIf` directive guards the message. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | There is no message if there is no user. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/title.component.html" region="ngIf" title="src/app/title.component.html (ngIf)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Although `AppModule` doesn't declare `NgIf`, the application still compiles and runs. | 
					
						
							|  |  |  | How can that be? The Angular compiler should either ignore or complain about unrecognized HTML. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Angular does recognize `NgIf` because you imported it earlier. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The initial version of `AppModule` imports `BrowserModule`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.0.ts" region="imports" title="src/app/app.module.ts (imports)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Importing `BrowserModule` made all of its public components, directives, and pipes visible | 
					
						
							|  |  |  | to the component templates in `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | More accurately, `NgIf` is declared in `CommonModule` from `@angular/common`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | `CommonModule` contributes many of the common directives that applications need, including `ngIf` and `ngFor`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | `BrowserModule` imports `CommonModule` and [re-exports](guide/ngmodule-faq#q-re-export) it. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The net effect is that an importer of `BrowserModule` gets `CommonModule` directives automatically. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Many familiar Angular directives don't belong to `CommonModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | For example,  `NgModel` and `RouterLink` belong to Angular's `FormsModule` and `RouterModule` respectively. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You must import those modules before you can use their directives. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | To illustrate this point, you'll extend the sample app with `ContactComponent`, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | a form component that imports form support from the Angular `FormsModule`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Add the _ContactComponent_</h3> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | [Angular forms](guide/forms) are a great way to manage user data entry. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The `ContactComponent` presents a "contact editor," | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | implemented with Angular forms in the [template-driven form](guide/forms#template-driven) style. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Angular form styles</h3> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You can write Angular form components in | 
					
						
							|  |  |  | template-driven or | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [reactive](guide/dynamic-form) style. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | <!-- CF: this link goes to a page titled "Dynamic Forms". Should the link text be "dynamic" instead of "reactive"? --> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The following sample imports the `FormsModule` from `@angular/forms` because | 
					
						
							|  |  |  | the `ContactComponent` is written in _template-driven_ style. | 
					
						
							|  |  |  | Modules with components written in the _reactive_ style | 
					
						
							|  |  |  | import the `ReactiveFormsModule`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `ContactComponent` selector matches an element named `<app-contact>`. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Add an element with that name to the `AppComponent` template, just below the `<app-title>`: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.component.1b.ts" region="template" title="src/app/app.component.ts (template)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Form components are often complex. The `ContactComponent` has its own `ContactService` | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | and [custom pipe](guide/pipes#custom-pipes) (called `Awesome`), | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | and an alternative version of the `HighlightDirective`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | To make it manageable, place all contact-related material in an `src/app/contact` folder | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | and break the component into three constituent HTML, TypeScript, and css files: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-tabs> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="src/app/contact/contact.component.html" path="ngmodule/src/app/contact/contact.component.html"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/contact/contact.component.ts" path="ngmodule/src/app/contact/contact.component.3.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/contact/contact.component.css" path="ngmodule/src/app/contact/contact.component.css"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/contact/contact.service.ts" path="ngmodule/src/app/contact/contact.service.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/contact/awesome.pipe.ts" path="ngmodule/src/app/contact/awesome.pipe.ts"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="src/app/contact/highlight.directive.ts" path="ngmodule/src/app/contact/highlight.directive.ts"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | In the middle of the component template, | 
					
						
							|  |  |  | notice the two-way data binding `[(ngModel)]`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | `ngModel` is the selector for the `NgModel` directive. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Although `NgModel` is an Angular directive, the _Angular compiler_ won't recognize it for the following reasons: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * `AppModule` doesn't declare `NgModel`. | 
					
						
							|  |  |  | * `NgModel` wasn't imported via `BrowserModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Even if Angular somehow recognized `ngModel`, | 
					
						
							|  |  |  | `ContactComponent` wouldn't behave like an Angular form because | 
					
						
							|  |  |  | form features such as validation aren't yet available. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Import the FormsModule</h3> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Add the `FormsModule` to the `AppModule` metadata's `imports` list. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.1.ts" region="imports" title="src/app/app.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Now `[(ngModel)]` binding will work and the user input will be validated by Angular forms, | 
					
						
							|  |  |  | once you declare the new component, pipe, and directive. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="alert is-critical"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | *Do not* add `NgModel`—or the `FORMS_DIRECTIVES`—to | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | the `AppModule` metadata's declarations. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | These directives belong to the `FormsModule`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Components, directives, and pipes belong to _one module only_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | *Never re-declare classes that belong to another module.* | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a declare-pipe} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Declare the contact component, directive, and pipe</h3> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The application won't compile until you declare the contact component, directive, and pipe. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Update the `declarations` in the  `AppModule` accordingly: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.1.ts" region="declarations" title="src/app/app.module.ts (declarations)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a import-name-conflict} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | There are two directives with the same name, both called `HighlightDirective`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | To work around this, create an alias for the contact version using the `as` JavaScript import keyword. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.1b.ts" region="import-alias" title="src/app/app.module.1b.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This solves the immediate issue of referencing both directive _types_ in the same file but | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | leaves another issue unresolved. | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | You'll learn more about that issue later in this page, in [Resolve directive conflicts](guide/ngmodule#resolve-conflicts). | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Provide the _ContactService_</h3> | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The `ContactComponent` displays contacts retrieved by the `ContactService`, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | which Angular injects into its constructor. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You have to provide that service somewhere. | 
					
						
							|  |  |  | The `ContactComponent` could provide it, | 
					
						
							|  |  |  | but then the service would be scoped to this component only. | 
					
						
							|  |  |  | You want to share this service with other contact-related components that you'll surely add later. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | In this app, add `ContactService` to the `AppModule` metadata's `providers` list: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.1b.ts" region="providers" title="src/app/app.module.ts (providers)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Now you can inject `ContactService` (like `UserService`) into any component in the application. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a application-scoped-providers} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Application-scoped providers</h3> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   The `ContactService` provider is _application_-scoped because Angular | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |   registers a module's `providers` with the application's *root injector*. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Architecturally, the `ContactService` belongs to the Contact business domain. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |   Classes in other domains don't need the `ContactService` and shouldn't inject it. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |   You might expect Angular to offer a _module_-scoping mechanism to enforce this design. | 
					
						
							|  |  |  |   It doesn't. NgModule instances, unlike components, don't have their own injectors | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   so they can't have their own provider scopes. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   This omission is intentional. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |   NgModules are designed primarily to extend an application, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   to enrich the entire app with the module's capabilities. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |   In practice, service scoping is rarely an issue. | 
					
						
							|  |  |  |   Non-contact components can't accidentally inject the `ContactService`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |   To inject `ContactService`, you must first import its _type_. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |   Only Contact components should import the `ContactService` type. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  |   Read more in the [How do I restrict service scope to a module?](guide/ngmodule-faq#q-component-scoped-providers) section | 
					
						
							|  |  |  |   of the [NgModule FAQs](guide/ngmodule-faq) page. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Run the app</h3> | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Everything is in place to run the application with its contact editor. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The app file structure looks like this: | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  | <div class='filetree'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |   <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     app | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |   </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <div class='children'> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       app.component.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       app.module.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       highlight.directive.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       title.component.(html|ts) | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       user.service.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       contact | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <div class='children'> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |         awesome.pipe.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |       <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |         contact.component.(css|html|ts) | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |       <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |         contact.service.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |       <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |         highlight.directive.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |   </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Try the example: | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:12:22 +03:00
										 |  |  | <live-example embedded plnkr="contact.1b" img="guide/ngmodule/contact-1b-plunker.png"></live-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a resolve-conflicts} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Resolve directive conflicts
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | <!-- CF: This section describes directive conflicts in detail, but doesn't describe how to resolve them.
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  |  This section seems like more of an introduction to the next section, "Feature modules". | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |  Consider moving this section to be a child section of "Feature modules", or striking "Resolve" from this title. --> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | An issue arose [earlier](guide/ngmodule#import-name-conflict) when you declared the contact's `HighlightDirective` because | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | you already had a `HighlightDirective` class at the application level. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The selectors of the two directives both highlight the attached element with a different color. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-tabs> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="src/app/highlight.directive.ts" path="ngmodule/src/app/highlight.directive.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/contact/highlight.directive.ts" path="ngmodule/src/app/contact/highlight.directive.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Both directives are declared in this module so both directives are active. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | When the two directives compete to color the same element, | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | the directive that's declared later wins because its DOM changes overwrite the first. | 
					
						
							|  |  |  | In this case, the contact's `HighlightDirective` makes the application title text blue | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | when it should stay gold. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The issue is that two different classes are trying to do the same thing. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | It's OK to import the same directive class multiple times. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Angular removes duplicate classes and only registers one of them. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | But from Angular's perspective, two different classes, defined in different files, that have the same name | 
					
						
							|  |  |  | are not duplicates. Angular keeps both directives and | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | they take turns modifying the same HTML element. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | At least the app still compiles. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | If you define two different component classes with the same selector specifying the same element tag, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | the compiler reports an error. It can't insert two components in the same DOM location. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | To eliminate component and directive conflicts, create feature modules | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that insulate the declarations in one module from the declarations in another. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a feature-modules} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | ## Feature modules
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This application isn't big yet, but it's already experiencing structural issues. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * The root `AppModule` grows larger with each new application class. | 
					
						
							|  |  |  | * There are conflicting directives. | 
					
						
							|  |  |  | The `HighlightDirective` in the contact re-colors the work done by the `HighlightDirective` declared in `AppModule`. | 
					
						
							|  |  |  | Also, it colors the application title text when it should color only the `ContactComponent`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | * The app lacks clear boundaries between contact functionality and other application features. | 
					
						
							|  |  |  | That lack of clarity makes it harder to assign development responsibilities to different teams. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You can resolve these issues with _feature modules_. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | A feature module is a class adorned by the `@NgModule` decorator and its metadata, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | just like a root module. | 
					
						
							|  |  |  | Feature module metadata have the same properties as the metadata for a root module. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The root module and the feature module share the same execution context. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | They share the same dependency injector, which means the services in one module | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | are available to all. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The modules have the following significant technical differences: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * You _boot_ the root module to _launch_ the app; | 
					
						
							|  |  |  | you _import_ a feature module to _extend_ the app. | 
					
						
							|  |  |  | * A feature module can expose or hide its implementation from other modules. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Otherwise, a feature module is distinguished primarily by its intent. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A feature module delivers a cohesive set of functionality | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | focused on an application business domain, user workflow, facility (forms, http, routing), | 
					
						
							|  |  |  | or collection of related utilities. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | While you can do everything within the root module, | 
					
						
							|  |  |  | feature modules help you partition the app into areas of specific interest and purpose. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | <!-- CF: Is this paragraph just restating the previous paragraph?
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | If so, I recommend removing it or merging the two --> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | A feature module collaborates with the root module and with other modules | 
					
						
							|  |  |  | through the services it provides and | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | the components, directives, and pipes that it shares. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | In the next section, you'll carve the contact functionality out of the root module | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | and into a dedicated feature module. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | {@a contact-module-v1} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### Make _Contact_ a feature module
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | <!-- CF: Is "Contact" a proper noun in this context? --> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | It's easy to refactor the contact material into a contact feature module. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1. Create the `ContactModule` in the `src/app/contact` folder. | 
					
						
							|  |  |  | 1. Move the contact material from `AppModule` to `ContactModule`. | 
					
						
							|  |  |  | 1. Replace the imported  `BrowserModule` with `CommonModule`. | 
					
						
							|  |  |  | 1. Import the `ContactModule` into the `AppModule`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | `AppModule` is the only existing class that changes. But you do add one new file. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### Add the _ContactModule_
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Here's the new `ContactModule`: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/contact/contact.module.2.ts" title="src/app/contact/contact.module.ts"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You copy from `AppModule` the contact-related import statements and `@NgModule` properties | 
					
						
							|  |  |  | that concern the contact, and paste them into `ContactModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You _import_ the `FormsModule` because the contact component needs it. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="alert is-important"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Modules don't inherit access to the components, directives, or pipes that are declared in other modules. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | What `AppModule` imports is irrelevant to `ContactModule` and vice versa. | 
					
						
							|  |  |  | Before `ContactComponent` can bind with `[(ngModel)]`, its `ContactModule` must import `FormsModule`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You also replaced `BrowserModule` by `CommonModule`, for reasons explained in the | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [Should I import BrowserModule or CommonModule?](guide/ngmodule-faq#q-browser-vs-common-module) | 
					
						
							|  |  |  | section of the [NgModule FAQs](guide/ngmodule-faq) page. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You _declare_ the contact component, directive, and pipe in the module `declarations`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You _export_ the `ContactComponent` so | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | other modules that import the `ContactModule` can include it in their component templates. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | All other declared contact classes are private by default. | 
					
						
							|  |  |  | The `AwesomePipe` and `HighlightDirective` are hidden from the rest of the application. | 
					
						
							|  |  |  | The `HighlightDirective` can no longer color the `AppComponent` title text. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### Refactor the _AppModule_
 | 
					
						
							|  |  |  | Return to the `AppModule` and remove everything specific to the contact feature set. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * Delete the contact import statements. | 
					
						
							|  |  |  | * Delete the contact declarations and contact providers. | 
					
						
							|  |  |  | * Delete the `FormsModule` from the `imports` list (`AppComponent` doesn't need it). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Leave only the classes required at the application root level. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Then import the `ContactModule` so the app can continue to display the exported `ContactComponent`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Here's the refactored version of the `AppModule` along with the previous version. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-tabs> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="src/app/app.module.ts (v2)" path="ngmodule/src/app/app.module.2.ts"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/app.module.ts (v1)" path="ngmodule/src/app/app.module.1b.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Improvements
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There's a lot to like in the revised `AppModule`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | * It does not change as the _Contact_ domain grows. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * It only changes when you add new modules. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | * It's simpler: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  |   * Fewer import statements. | 
					
						
							|  |  |  |   * No `FormsModule` import. | 
					
						
							|  |  |  |   * No contact-specific declarations. | 
					
						
							|  |  |  |   * No `ContactService` provider. | 
					
						
							|  |  |  |   * No `HighlightDirective` conflict. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Try this `ContactModule` version of the sample. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:12:22 +03:00
										 |  |  | <live-example embedded plnkr="contact.2" img="guide/ngmodule/contact-2-plunker.png">Try the live example.</live-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a lazy-load} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | ## Lazy-loading modules with the router
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The Heroic Staffing Agency sample app has evolved. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | It has two more modules, one for managing the heroes on staff and another for matching crises to the heroes. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Both modules are in the early stages of development. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Their specifics aren't important to the story and this page doesn't discuss every line of code. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | Examine and download the complete source for this version from | 
					
						
							| 
									
										
										
										
											2017-04-26 15:12:22 +03:00
										 |  |  | the <live-example plnkr="pre-shared.3" img="guide/ngmodule/v3-plunker.png">live example.</live-example> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Some facets of the current application merit discussion are as follows: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | * The app has three feature modules: Contact, Hero, and Crisis. | 
					
						
							|  |  |  | * The Angular router helps users navigate among these modules. | 
					
						
							|  |  |  | * The `ContactComponent` is the default destination when the app starts. | 
					
						
							|  |  |  | * The `ContactModule` continues to be "eagerly" loaded when the application starts. | 
					
						
							|  |  |  | * `HeroModule` and the `CrisisModule` are lazy loaded. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | {@a app-component-template} | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The new `AppComponent` template has | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | a title, three links, and a `<router-outlet>`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.component.3.ts" region="template" title="src/app/app.component.ts (v3 - Template)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The `<app-contact>` element is gone; you're routing to the _Contact_ page now. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `AppModule` has changed modestly: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.3.ts" title="src/app/app.module.ts (v3)"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Some file names bear a `.3` extension that indicates | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | a difference with prior or future versions. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The significant differences will be explained in due course. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | <!-- CF: Can you be more specific here? Are the differences explained later in this page or in another page? --> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The module still imports `ContactModule` so that its routes and components are mounted when the app starts. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The module does _not_ import `HeroModule` or `CrisisModule`. | 
					
						
							|  |  |  | They'll be fetched and mounted asynchronously when the user navigates to one of their routes. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The significant change from version 2 is the addition of the *AppRoutingModule* to the module `imports`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | The `AppRoutingModule` is a [routing module](guide/router#routing-module) | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that handles the app's routing concerns. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### App routing
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app-routing.module.ts" title="src/app/app-routing.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | The router is the subject of the [Routing & Navigation](guide/router) page, so this section skips many of the details and | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | concentrates on the intersection of NgModules and routing. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The `app-routing.module.ts` file defines three routes. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The first route redirects the empty URL (such as `http://host.com/`) | 
					
						
							|  |  |  | to another route whose path is `contact` (such as `http://host.com/contact`). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `contact` route isn't defined here. | 
					
						
							|  |  |  | It's defined in the _Contact_ feature's _own_ routing module, `contact-routing.module.ts`. | 
					
						
							|  |  |  | It's standard practice for feature modules with routing components to define their own routes. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You'll get to that file in a moment. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The remaining two routes use lazy loading syntax to tell the router where to find the modules: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app-routing.module.ts" region="lazy-routes" title="src/app/app-routing.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | A lazy-loaded module location is a _string_, not a _type_. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | In this app, the string identifies both the module _file_ and the module _class_, | 
					
						
							|  |  |  | the latter separated from the former by a `#`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### RouterModule.forRoot
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The `forRoot` static class method of the `RouterModule` with the provided configuration and | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | added to the `imports` array provides the routing concerns for the module. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app-routing.module.ts" region="forRoot" title="src/app/app-routing.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The returned `AppRoutingModule` class is a `Routing Module` containing both the `RouterModule` directives | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | and the dependency-injection providers that produce a configured `Router`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This `AppRoutingModule` is intended for the app _root_ module only. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="alert is-critical"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Never call `RouterModule.forRoot` in a feature-routing module. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Back in the root `AppModule`, add the `AppRoutingModule` to its `imports` list, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | and the app is ready to navigate. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.3.ts" region="imports" title="src/app/app.module.ts (imports)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### Routing to a feature module
 | 
					
						
							|  |  |  | The `src/app/contact` folder holds a new file, `contact-routing.module.ts`. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | It defines the `contact` route mentioned earlier and provides a `ContactRoutingModule` as follows: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/contact/contact-routing.module.ts" region="routing" title="src/app/contact/contact-routing.module.ts (routing)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | This time you pass the route list to the `forChild` method of the `RouterModule`. | 
					
						
							|  |  |  | The route list is only responsible for providing additional routes and is intended for feature modules. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="alert is-important"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Always call `RouterModule.forChild` in a feature-routing module. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="alert is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | _forRoot_ and _forChild_ are conventional names for methods that | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | deliver different `import` values to root and feature modules. | 
					
						
							|  |  |  | Angular doesn't recognize them but Angular developers do. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [Follow this convention](guide/ngmodule-faq#q-for-root) if you write a similar module | 
					
						
							|  |  |  | that has both shared [declarables](guide/ngmodule-faq#q-declarable) and services. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | `ContactModule` has changed in two small but important ways. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-tabs> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="src/app/contact/contact.module.3.ts" path="ngmodule/src/app/contact/contact.module.3.ts" region="class"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/contact/contact.module.2.ts" path="ngmodule/src/app/contact/contact.module.2.ts" region="class"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * It imports the `ContactRoutingModule` object from `contact-routing.module.ts`. | 
					
						
							|  |  |  | * It no longer exports `ContactComponent`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Now that you navigate to `ContactComponent` with the router, there's no reason to make it public. | 
					
						
							|  |  |  | Also, `ContactComponent` doesn't need a selector. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | No template will ever again reference this `ContactComponent`. | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | It's gone from the [AppComponent template](guide/ngmodule#app-component-template). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a hero-module} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | ### Lazy-loaded routing to a module
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The lazy-loaded `HeroModule` and `CrisisModule` follow the same principles as any feature module. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | They don't look different from the eagerly loaded `ContactModule`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The `HeroModule` is a bit more complex than the `CrisisModule`, which makes it | 
					
						
							|  |  |  | a more interesting and useful example. Its file structure is as follows: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  | <div class='filetree'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |   <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |     hero | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |   </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <div class='children'> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       hero-detail.component.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       hero-list.component.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       hero.component.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       hero.module.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       hero-routing.module.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       hero.service.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     <div class='file'> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  |       highlight.directive.ts | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |     </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  |   </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 21:44:52 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | This is the child routing scenario familiar to readers of the | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | [Child routing component](guide/router#child-routing-component) section of the | 
					
						
							|  |  |  | [Routing & Navigation](guide/router#child-routing-component) page. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `HeroComponent` is the feature's top component and routing host. | 
					
						
							|  |  |  | Its template has a `<router-outlet>` that displays either a list of heroes (`HeroList`) | 
					
						
							|  |  |  | or an editor of a selected hero (`HeroDetail`). | 
					
						
							|  |  |  | Both components delegate to the `HeroService` to fetch and save data. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Yet another `HighlightDirective` colors elements in yet a different shade. | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | In the next section, [Shared modules](guide/ngmodule#shared-module "Shared modules"), you'll resolve the repetition and inconsistencies. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `HeroModule` is a feature module like any other. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/hero/hero.module.3.ts" region="class" title="src/app/hero/hero.module.ts (class)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | It imports the `FormsModule` because the `HeroDetailComponent` template binds with `[(ngModel)]`. | 
					
						
							|  |  |  | It imports the `HeroRoutingModule` from `hero-routing.module.ts` just as `ContactModule` and `CrisisModule` do. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The `CrisisModule` is much the same. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:12:22 +03:00
										 |  |  | <live-example embedded plnkr="pre-shared.3" img="guide/ngmodule/v3-plunker.png">Try the live example.</live-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a shared-module} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Shared modules
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The app is shaping up. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | But it carries three different versions of the `HighlightDirective`. | 
					
						
							|  |  |  | And the many files cluttering the app folder level could be better organized. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Add a `SharedModule` to hold the common components, directives, and pipes | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | and share them with the modules that need them. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | 1. Create an `src/app/shared` folder. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 1. Move the `AwesomePipe` and `HighlightDirective` from `src/app/contact` to `src/app/shared`. | 
					
						
							|  |  |  | 1. Delete the `HighlightDirective` classes from `src/app/` and `src/app/hero`. | 
					
						
							|  |  |  | 1. Create a `SharedModule` class to own the shared material. | 
					
						
							|  |  |  | 1. Update other feature modules to import `SharedModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Here is the `SharedModule`: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/shared/shared.module.ts" title="src/app/src/app/shared/shared.module.ts"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Note the following: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | * It imports the `CommonModule` because its component needs common directives. | 
					
						
							|  |  |  | * It declares and exports the utility pipe, directive, and component classes as expected. | 
					
						
							|  |  |  | * It re-exports the `CommonModule` and `FormsModule` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Re-exporting other modules
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | If you review the application, you may notice that many components requiring `SharedModule` directives | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | also use `NgIf` and `NgFor` from `CommonModule` | 
					
						
							|  |  |  | and bind to component properties with `[(ngModel)]`, a directive in the `FormsModule`. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Modules that declare these components would have to import `CommonModule`, `FormsModule`, and `SharedModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You can reduce the repetition by having `SharedModule` re-export `CommonModule` and `FormsModule` | 
					
						
							|  |  |  | so that importers of `SharedModule` get `CommonModule` and `FormsModule` for free. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | As it happens, the components declared by `SharedModule` itself don't bind with `[(ngModel)]`. | 
					
						
							|  |  |  | Technically,  there is no need for `SharedModule` to import `FormsModule`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `SharedModule` can still export `FormsModule` without listing it among its `imports`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Why _TitleComponent_ isn't shared
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | `SharedModule` exists to make commonly used components, directives, and pipes available | 
					
						
							|  |  |  | for use in the templates of components in many other modules. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The `TitleComponent` is used only once by the `AppComponent`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | There's no point in sharing it. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | {@a no-shared-module-providers} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### Why _UserService_ isn't shared
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | While many components share the same service instances, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | they rely on Angular dependency injection to do this kind of sharing, not the module system. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Several components of the sample inject the `UserService`. | 
					
						
							|  |  |  | There should be only one instance of the `UserService` in the entire application | 
					
						
							|  |  |  | and only one provider of it. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | `UserService` is an application-wide singleton. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You don't want each module to have its own separate instance. | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | Yet there is [a real danger](guide/ngmodule-faq#q-why-bad) of that happening | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | <!-- CF: This link goes to the top of the NgModule FAQs page.
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | It looks like it is supposed to go to a specific question/section within the page. --> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | if the `SharedModule` provides the `UserService`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="alert is-critical"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Do *not* specify app-wide singleton `providers` in a shared module. | 
					
						
							|  |  |  | A lazy-loaded module that imports that shared module makes its own copy of the service. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a core-module} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## The Core module
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | At the moment, the root folder is cluttered with the `UserService` | 
					
						
							|  |  |  | and `TitleComponent` that only appear in the root `AppComponent`. | 
					
						
							|  |  |  | You didn't include them in the `SharedModule` for reasons just explained. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Instead, gather them in a single `CoreModule` that you import once when the app starts | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | and never import anywhere else. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Perform the following steps: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | 1. Create an `src/app/core` folder. | 
					
						
							|  |  |  | * Move the `UserService` and `TitleComponent` from `src/app/` to `src/app/core`. | 
					
						
							|  |  |  | * Create a `CoreModule` class to own the core material. | 
					
						
							|  |  |  | * Update the `AppRoot` module to  import `CoreModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Most of this work is familiar. The interesting part is the `CoreModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/core/core.module.ts" region="v4" title="src/app/src/app/core/core.module.ts"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You're importing some extra symbols from the Angular core library that you're not using yet. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | They'll become relevant later in this page. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | The `@NgModule` metadata should be familiar. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You declare the `TitleComponent`  because this module owns it and you export it | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | because `AppComponent` (which is in `AppModule`) displays the title in its template. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | `TitleComponent` needs the Angular `NgIf` directive that you import from `CommonModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | `CoreModule` provides the `UserService`. Angular registers that provider with the app root injector, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | making a singleton instance of the `UserService` available to any component that needs it, | 
					
						
							|  |  |  | whether that component is eagerly or lazily loaded. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | <h3 class="no-toc">Why bother?</h3> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | This scenario is clearly contrived. | 
					
						
							|  |  |  | The app is too small to worry about a single service file and a tiny, one-time component. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A `TitleComponent` sitting in the root folder isn't bothering anyone. | 
					
						
							|  |  |  | The root `AppModule` can register the `UserService` itself, | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | as it does currently, even if you decide to relocate the `UserService` file to the `src/app/core` folder. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Real-world apps have more to worry about. | 
					
						
							|  |  |  | They can have several single-use components (such as spinners, message toasts, and modal dialogs) | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that appear only in the `AppComponent` template. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You don't import them elsewhere so they're not shared in that sense. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Yet they're too big and messy to leave loose in the root folder. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Apps often have many singleton services like this sample's `UserService`. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Each must be registered exactly once, in the app root injector, when the application starts. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | While many components inject such services in their constructors—and | 
					
						
							|  |  |  | therefore require JavaScript `import` statements to import their symbols—no | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | other component or module should define or re-create the services themselves. | 
					
						
							|  |  |  | Their _providers_ aren't shared. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | We recommend collecting such single-use classes and hiding their details inside a `CoreModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | A simplified root `AppModule` imports `CoreModule` in its capacity as orchestrator of the application as a whole. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Cleanup
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Having refactored to a `CoreModule` and a `SharedModule`, it's time to clean up the other modules. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### A trimmer _AppModule_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Here is the updated `AppModule` paired with version 3 for comparison: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/app.module.ts (v4)" path="ngmodule/src/app/app.module.ts" region="v4"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/app.module.ts (v3)" path="ngmodule/src/app/app.module.3.ts"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | `AppModule` now has the following qualities: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * A little smaller because many `src/app/root` classes have moved to other modules. | 
					
						
							|  |  |  | * Stable because you'll add future components and providers to other modules, not this one. | 
					
						
							|  |  |  | * Delegated to imported modules rather than doing work. | 
					
						
							|  |  |  | * Focused on its main task, orchestrating the app as a whole. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### A trimmer _ContactModule_
 | 
					
						
							|  |  |  | Here is the new `ContactModule` paired with the prior version: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-tabs> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="src/app/contact/contact.module.ts (v4)" path="ngmodule/src/app/contact/contact.module.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="src/app/contact/contact.module.ts (v3)" path="ngmodule/src/app/contact/contact.module.3.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Notice the following: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | * The `AwesomePipe` and `HighlightDirective` are gone. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * The imports include `SharedModule` instead of `CommonModule` and `FormsModule`. | 
					
						
							|  |  |  | * The new version is leaner and cleaner. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <hr/> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a core-for-root} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Configure core services with _CoreModule.forRoot_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A module that adds providers to the application can offer a facility for configuring those providers as well. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | By convention, the `forRoot` static method both provides and configures services at the same time. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | It takes a service configuration object and returns a | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [ModuleWithProviders](api/core/ModuleWithProviders), which is | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | a simple object with the following properties: | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | * `ngModule`: the `CoreModule` class | 
					
						
							|  |  |  | * `providers`: the configured providers | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The root `AppModule` imports the `CoreModule` and adds the `providers` to the `AppModule` providers. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | More precisely, Angular accumulates all imported providers before appending the items listed in `@NgModule.providers`. | 
					
						
							|  |  |  | This sequence ensures that whatever you add explicitly to the `AppModule` providers takes precedence | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | over the providers of imported modules. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | Add a `CoreModule.forRoot` method that configures the core `UserService`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You've extended the core `UserService` with an optional, injected `UserServiceConfig`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | If a `UserServiceConfig` exists, the `UserService` sets the user name from that config. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/core/user.service.ts" region="ctor" title="src/app/core/user.service.ts (constructor)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Here's `CoreModule.forRoot` that takes a `UserServiceConfig` object: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/core/core.module.ts" region="for-root" title="src/app/core/core.module.ts (forRoot)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Lastly, call it within the `imports` list of the `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/app.module.ts" region="import-for-root" title="src/app//app.module.ts (imports)" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The app displays "Miss Marple" as the user instead of the default "Sherlock Holmes". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="alert is-important"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Call `forRoot` only in the root application module, `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Calling it in any other module, particularly in a lazy-loaded module, | 
					
						
							|  |  |  | is contrary to the intent and can produce a runtime error. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Remember to _import_ the result; don't add it to any other `@NgModule` list. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <hr/> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a prevent-reimport} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Prevent reimport of the _CoreModule_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Only the root `AppModule` should import the `CoreModule`. | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [Bad things happen](guide/ngmodule-faq#q-why-bad) if a lazy-loaded module imports it. | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | <!-- CF: Again, this link goes to the top of the NgModule FAQs page.
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | It looks like it is supposed to go to a specific question/section within the page. --> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | You could hope that no developer makes that mistake. | 
					
						
							|  |  |  | Or you can guard against it and fail fast by adding the following `CoreModule` constructor. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | <code-example path="ngmodule/src/app/core/core.module.ts" region="ctor" title="src/app/core/core.module.ts" linenums="false"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The constructor tells Angular to inject the `CoreModule` into itself. | 
					
						
							|  |  |  | That seems dangerously circular. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | The injection would be circular if Angular looked for `CoreModule` in the _current_ injector. | 
					
						
							|  |  |  | The `@SkipSelf` decorator means "look for `CoreModule` in an ancestor injector, above me in the injector hierarchy." | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | If the constructor executes as intended in the `AppModule`, | 
					
						
							|  |  |  | there is no ancestor injector that could provide an instance of `CoreModule`. | 
					
						
							|  |  |  | The injector should give up. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | By default, the injector throws an error when it can't find a requested provider. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `@Optional` decorator means not finding the service is OK. | 
					
						
							|  |  |  | The injector returns `null`, the `parentModule` parameter is null, | 
					
						
							|  |  |  | and the constructor concludes uneventfully. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | It's a different story if you improperly import `CoreModule` into a lazy-loaded module such as `HeroModule` (try it). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Angular creates a lazy-loaded module with its own injector, a _child_ of the root injector. | 
					
						
							|  |  |  | `@SkipSelf` causes Angular to look for a `CoreModule` in the parent injector, which this time is the root injector. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Of course it finds the instance imported by the root `AppModule`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | Now `parentModule` exists and the constructor throws the error. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | ## Conclusion
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | You made it! You can examine and download the complete source for this final version from the live example. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:12:22 +03:00
										 |  |  | <live-example embedded  img="guide/ngmodule/final-plunker.png"></live-example> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 20:47:34 -07:00
										 |  |  | ## Frequently asked questions
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Now that you understand NgModules, you may be interested | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | in the companion [NgModule FAQs](guide/ngmodule-faq "NgModule FAQs") page | 
					
						
							| 
									
										
										
										
											2017-04-24 20:23:45 +02:00
										 |  |  | with its ready answers to specific design and implementation questions. |