Simplified routing in tutorial example Updated ngmodule guide and ngmodule faq with routing module prose
		
			
				
	
	
		
			1177 lines
		
	
	
		
			50 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1177 lines
		
	
	
		
			50 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| block includes
 | |
|   include ../_util-fns
 | |
| 
 | |
| :marked
 | |
|   # FAQs
 | |
| 
 | |
|   **Angular Modules** help organize an application into cohesive blocks of functionality.
 | |
| 
 | |
|   The [Angular Modules chapter](../guide/ngmodule.html) covers the concepts and takes you step by step
 | |
|   from the most elementary `@NgModule` to a multi-faceted sample with lazy loaded modules.
 | |
| 
 | |
|   _This_ chapter answers the questions many developers ask about Angular Module design and implementation.
 | |
| .alert.is-important
 | |
|   :marked
 | |
|     These FAQs assume that you have already read the [Angular Module](../guide/ngmodule.html) chapter.
 | |
| 
 | |
| :marked
 | |
|   Declarations
 | |
|   * [What classes should I add to _declarations_?](#q-what-to-declare)
 | |
|   * [What is a _declarable_?](#q-declarable)
 | |
|   * [What classes should I *not* add to _declarations_?](#q-what-not-to-declare)
 | |
|   * [Why list the same component in multiple _NgModule_ properties?](#q-why-multiple-mentions)
 | |
|   * [What does "_Can't bind to 'x' since it isn't a known property of 'y'_" mean?](#q-why-cant-bind-to)
 | |
| 
 | |
|   Imports
 | |
|   * [What should I import?](#q-what-to-import)
 | |
|   * [Should I import _BrowserModule_ or _CommonModule_?](#q-browser-vs-common-module)
 | |
|   * [What if I import the same module twice?](#q-reimport)
 | |
| 
 | |
|   Exports
 | |
|   * [What should I export?](#q-what-to-export)
 | |
|   * [What should I *not* export?](#q-what-not-to-export)
 | |
|   * [Can I re-export imported classes and modules?](#q-re-export)
 | |
|   * [What is the _forRoot_ method?](#q-for-root)
 | |
| 
 | |
|   Service Providers
 | |
|   * [Why is a service provided in a feature module visible everywhere?](#q-module-provider-visibility)
 | |
|   * [Why is a service provided in a _lazy loaded_ module visible only to that module?](#q-lazy-loaded-module-provider-visibility)
 | |
|   * [What if two modules provide the _same_ service?](#q-module-provider-duplicates)
 | |
|   * [How do I restrict service scope to a module?](#q-component-scoped-providers)
 | |
|   * [Should I add app-wide providers to the root _AppModule_ or the root _AppComponent_?](#q-root-component-or-module)
 | |
|   * [Should I add other providers to a module or a component?](#q-component-or-module)
 | |
|   * [Why is it bad if _SharedModule_ provides a service to a lazy loaded module?](#q-why-bad)
 | |
|   * [Why does lazy loading create a child injector?](#q-why-child-injector)
 | |
|   * [How can I tell if a module or service was previously loaded?](#q-is-it-loaded)
 | |
| 
 | |
|   Entry Components
 | |
|   * [What is an _entry component_?](#q-entry-component-defined)
 | |
|   * [What is the difference between a _bootstrap_ component and an _entry component_?](#q-bootstrap_vs_entry_component)
 | |
|   * [When do I add components to _entryComponents_?](#q-when-entry-components)
 | |
|   * [Why does Angular need _entryComponents_?](#q-why-entry-components)
 | |
| 
 | |
|   General
 | |
|   * [What kinds of modules should I have and how should I use them?](#q-module-recommendations)
 | |
|   * [What's the difference between Angular and JavaScript Modules?](#q-ng-vs-js-modules)
 | |
|   * [What is a "template reference"?](#q-template-reference)
 | |
|   * [How does Angular find components, directives, and pipes in a template?](#q-template-reference)
 | |
|   * [What is the Angular Compiler?](#q-angular-compiler)
 | |
|   * [Can you summarize the _NgModule_ API?](#q-ngmodule-api)
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-what-to-declare
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What classes should I add to _declarations_?
 | |
| 
 | |
|   Add [declarable](#q-declarable) classes — components, directives, and pipes — to a `declarations` list.
 | |
| 
 | |
|   These classes must be declared in _exactly one_ module of the application.
 | |
|   Declare them in _this_ module if they _belong_ to this module.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-declarable
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What is a _declarable_?
 | |
| 
 | |
|   _Declarables_ are the class types — components, directives, and pipes —
 | |
|   that you can add to a module's `declarations` list.
 | |
|   They're the _only_ classes that you can add to `declarations`.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-what-not-to-declare
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What classes should I _not_ add to _declarations_?
 | |
| 
 | |
|   Only [declarable](#q-declarable) classes can be added to a module's `declarations` list.
 | |
| 
 | |
|   Do *not* declare
 | |
|   * a class that is already declared in another module, whether an app module, @angular module, or 3rd party module
 | |
| 
 | |
|   * an array of directives imported from another module.
 | |
|   For example, do not declare FORMS_DIRECTIVES from `@angular/forms`.
 | |
| 
 | |
|   * module classes
 | |
| 
 | |
|   * service classes
 | |
| 
 | |
|   * non-Angular classes and objects such as
 | |
|   strings, numbers, functions, entity models, configurations, business logic, and helper classes.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-why-multiple-mentions
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Why list the same component in multiple _NgModule_ properties?
 | |
| 
 | |
|   We often see `AppComponent` listed in both `declarations` and `bootstrap`.
 | |
|   We might see `HeroComponent` listed in `declarations`, `exports`, and `entryComponents`.
 | |
| 
 | |
|   That _feels_ redundant but these properties have different functions
 | |
|   and we can't infer that membership in one list implies membership in another list.
 | |
| 
 | |
|   * `AppComponent` could be declared in this module but not bootstrapped.
 | |
|   * `AppComponent` could be bootstrapped in this module but declared in a different feature module.
 | |
|   * `HeroComponent` could be imported from another app module (so we can't declare it) and re-exported by this module.
 | |
|   * `HeroComponent` could be exported for inclusion in an external component's template and also dynamically loaded in a pop-up dialog.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-why-cant-bind-to
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What does "_Can't bind to 'x' since it isn't a known property of 'y'_" mean?
 | |
| 
 | |
|   This error usually means either that you neglected to declare the directive "x"
 | |
|   or you haven't imported the module to which "x" belongs.
 | |
| 
 | |
|   For example, if "x" is `ngModel`, you probably haven't imported the `FormsModule` from `@angular/forms`.
 | |
| 
 | |
|   Perhaps you declared "x" in an application sub-module but forgot to export it?
 | |
|   The "x" class won't be visible to other modules until you add it to the `exports` list.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-what-to-import
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What should I import?
 | |
| 
 | |
|   Import modules whose public (exported) [declarable classes](#q-declarable)
 | |
|   you need to reference in this module's component templates.
 | |
| 
 | |
|   This invariably means importing `CommonModule` from `@angular/common` for access to
 | |
|   the Angular directives such as `NgIf` and `NgFor`.
 | |
|   You can import it directly or from another module that [re-exports](#q-reexport) it.
 | |
| 
 | |
|   Import `FormsModule` from `@angular/forms`
 | |
|   if your components have `[(ngModel)]` two-way binding expressions.
 | |
| 
 | |
|   Import _shared_ and _feature_ modules when this module's components incorporate their
 | |
|   components, directives, and pipes.
 | |
| 
 | |
|   Only [import _BrowserModule_](#q-browser-vs-common-module) in the root `AppModule`.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-browser-vs-common-module
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Should I import _BrowserModule_ or _CommonModule_?
 | |
| 
 | |
|   The **root application module** (`AppModule`) of almost every browser application
 | |
|   should import `BrowserModule` from `@angular/platform-browser`.
 | |
| 
 | |
|   `BrowserModule` provides services that are essential to launch and run a browser app.
 | |
| 
 | |
|   `BrowserModule` also re-exports `CommonModule` from `@angular/common`
 | |
|   which means that component in the `AppModule` module also have access to
 | |
|   the Angular directives every app needs such as `NgIf` and `NgFor`.
 | |
| 
 | |
|   _Do not import_ `BrowserModule` in any other module.
 | |
|   *Feature modules* and *lazy loaded modules* should import `CommonModule` instead.
 | |
|   They need the common directives. They don't need to re-install the app-wide providers.
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     `BrowserModule` throws an error if you try to lazy load  a module that imports it.
 | |
| :marked
 | |
|   Importing `CommonModule` also frees feature modules for use on _any_ target platform, not just browsers,
 | |
|   a fact of some interest to authors of cross-platform libraries.
 | |
| 
 | |
| .l-hr
 | |
| a#q-reimport
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What if I import the same module twice?
 | |
| 
 | |
|   That's not a problem. When three modules all import Module 'A',
 | |
|   Angular evaluates Module 'A' once, the first time it encounters it, and does not do so again.
 | |
| 
 | |
|   That's true at whatever level `A` appears in a hierarchy of imported modules.
 | |
|   When Module 'B' imports Module 'A', Module 'C' imports 'B', and Module 'D' imports `[C, B, A]`,
 | |
|   then 'D' triggers the evaluation of 'C' which triggers the evaluation of 'B' which evaluates 'A'.
 | |
|   When Angular gets to the 'B' and 'A' in 'D', they're already cached and ready to go.
 | |
| 
 | |
|   Angular does not like modules with circular references so don't let Module 'A' import Module 'B' which imports Module 'A'.
 | |
| 
 | |
| .l-hr
 | |
| a#q-what-to-export
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What should I export?
 | |
| 
 | |
|   Export [declarable](#q-declarable) classes that components in _other_ modules
 | |
|   should be able to reference in their templates. These are your _public_ classes.
 | |
|   If you don't export a class, it stays _private_, visible only to other component
 | |
|   declared in this module.
 | |
| 
 | |
|   You _can_ export any declarable class — components, directives, and pipes —
 | |
|   whether it is declared in this module or in an imported module.
 | |
| 
 | |
|   You _can_ re-export entire imported modules which effectively re-exports all of their exported classes.
 | |
|   A module can even export a module that it doesn't import.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-what-not-to-export
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What should I *not* export?
 | |
| 
 | |
|   Do *not* export
 | |
| 
 | |
|   * Private components, directives, and pipes that you need only within components declared in this module.
 | |
|   If you don't want another module to see it, don't export it.
 | |
| 
 | |
|   * Non-declarable objects such as services, functions, configurations, entity models, etc.
 | |
| 
 | |
|   * Components that are only loaded dynamically by the router or by bootstrapping.
 | |
|   Such [entry components](#q-entry-component-defined) can never be selected in another component's template.
 | |
|   There's no harm in exporting them but no benefit either.
 | |
| 
 | |
|   * Pure service modules that don't have public (exported) declarations.
 | |
|   For example, there is no point in re-exporting `HttpModule` because it doesn't export anything.
 | |
|   It's only purpose is to add http service providers to the application as a whole.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-reexport
 | |
| a#q-re-export
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Can I re-export classes and modules?
 | |
| 
 | |
|   Absolutely!
 | |
| 
 | |
|   Modules are a great way to selectively aggregate classes from other modules and
 | |
|   re-export them in a consolidated, convenience module.
 | |
| 
 | |
|   A module can re-export entire modules which effectively re-exports all of their exported classes.
 | |
|   Angular's own `BrowserModule` exports a couple of modules like this:
 | |
| code-example.
 | |
|   exports: [CommonModule, ApplicationModule]
 | |
| 
 | |
| :marked
 | |
|   A module can export a combination of its own declarations, selected imported classes, and imported modules.
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Don't bother re-exporting pure service modules.
 | |
|     Pure service modules don't export [declarable](#q-declarable) classes that another module could use.
 | |
|     For example, there is no point in re-exporting `HttpModule` because it doesn't export anything.
 | |
|     It's only purpose is to add http service providers to the application as a whole.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-for-root
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What is the _forRoot_ method?
 | |
| 
 | |
|   The `forRoot` static method is a convention that makes it easy for developers to configure the module's provider(s).
 | |
| 
 | |
|   The `RouterModule.forRoot` method is a good example.
 | |
|   Apps pass a `Routes` object to `RouterModule.forRoot` in order to configure the app-wide `Router` service with routes.
 | |
|   `RouterModule.forRoot` returns a [ModuleWithProviders](../api/core/index/ModuleWithProviders-interface.html).
 | |
|   We add that result to the `imports` list of the root `AppModule`.
 | |
| 
 | |
| .alert.is-important
 | |
|   :marked
 | |
|     Only call and import a `.forRoot` result in the root application module, `AppModule`.
 | |
|     Importing it in any other module, particularly in a lazy loaded module,
 | |
|     is contrary to the intent and is likely to produce a runtime error.
 | |
| :marked
 | |
|   `RouterModule` also offers a `forChild` static method for configuring the routes of lazy loaded modules.
 | |
| 
 | |
|   **_forRoot_** and **_forChild_** are conventional names for methods that
 | |
|   configure services in root and feature modules respectively.
 | |
| 
 | |
|   Angular doesn't recognize these names but Angular developers do.
 | |
|   Follow this convention when you write similar modules with configurable service providers.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-module-provider-visibility
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Why is a service provided in a feature module visible everywhere?
 | |
| 
 | |
|   Providers listed in the `@NgModule.providers` of a bootstrapped module have **application scope**.
 | |
|   Adding a service provider to `@NgModule.providers` effectively publishes the service to the entire application.
 | |
| 
 | |
|   When we import a module,
 | |
|   Angular adds the module's service providers (the contents of its `providers` list)
 | |
|   to the application _root injector_.
 | |
| 
 | |
|   This makes the provider visible to every class in the application that knows the provider's lookup token.
 | |
| 
 | |
|   This is by design.
 | |
|   Extensibility through module imports is a primary goal of the Angular module system.
 | |
|   Merging module providers into the application injector
 | |
|   makes it easy for a module library to enrich the entire application with new services.
 | |
|   By adding the `HttpModule` once, every application component can make http requests.
 | |
| 
 | |
|   However, this can feel like an unwelcome surprise if you are expecting the module's services
 | |
|   to be visible only to the components declared by that feature module.
 | |
|   If the `HeroModule` provides the `HeroService` and the root `AppModule` imports `HeroModule`,
 | |
|   any class that knows the `HeroService` _type_ can inject that service,
 | |
|   not just the classes declared in the `HeroModule`.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-lazy-loaded-module-provider-visibility
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Why is a service provided in a lazy loaded module visible only to that module?
 | |
| 
 | |
|   Unlike providers of the modules loaded at launch,
 | |
|   providers of lazy loaded modules are *module-scoped*.
 | |
| 
 | |
|   When the Angular router lazy-loads a module, it creates a new execution context.
 | |
|   That [context has its own injector](#q-why-child-injector "Why Angular creates a child injector") which is a direct child of the application injector.
 | |
| 
 | |
|   The router adds the lazy module's providers and the providers of its imported modules to this child injector.
 | |
| 
 | |
|   These providers are insulated from changes to application providers with the same lookup token.
 | |
|   When the router creates a component within the lazy loaded context,
 | |
|   Angular prefers service instances created from these providers to the service instances of the application root injector.
 | |
| 
 | |
| .l-hr
 | |
| a#q-module-provider-duplicates
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What if two modules provide the _same_ service?
 | |
| 
 | |
|   When two imported modules, loaded at the same time, list a provider with the same token,
 | |
|   the second module's provider "wins". That's because both providers are added to the same injector.
 | |
| 
 | |
|   When Angular looks to inject a service for that token,
 | |
|   it creates and delivers the instance created by the second provider.
 | |
| 
 | |
|   _Every_ class that injects this service gets the instance created by the second provider.
 | |
|   Even classes declared within the first module get the instance created by the second provider.
 | |
|   _This can be an unwelcome surprise_.
 | |
| 
 | |
|   If Module A provides a service for token 'X' and imports a module B
 | |
|   that also provides a service for token 'X', then Module A's service definition "wins".
 | |
| 
 | |
|   The service provided by the root `AppModule` takes precedence over services provided by imported modules.
 | |
|   The `AppModule` always wins.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-component-scoped-providers
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### How do I restrict service scope to a module?
 | |
| 
 | |
|   When a module is loaded at application launch,
 | |
|   its `@NgModule.providers` have ***application-wide scope***.
 | |
|   They are available for injection throughout the application.
 | |
| 
 | |
|   Imported providers are easily replaced by providers from another imported module.
 | |
|   Such replacement may be by design. It could be unintentional and have adverse consequences.
 | |
| 
 | |
| .alert.is-important
 | |
|   :marked
 | |
|     As a general rule, import modules with providers _exactly once_, preferably in the application's _root module_.
 | |
|     That's also usually the best place to configure, wrap, and override them.
 | |
| 
 | |
| :marked
 | |
|   Suppose a module requires a customized `HttpBackend` that adds a special header for all Http requests.
 | |
|   If another module elsewhere in the application also customizes `HttpBackend`
 | |
|   or merely imports the `HttpModule`, it could override this module's `HttpBackend` provider,
 | |
|   losing the special header. The server will reject http requests from this module.
 | |
| 
 | |
| .alert.is-important
 | |
|   :marked
 | |
|     Avoid this problem by importing the `HttpModule` only in the `AppModule`, the application _root module_.
 | |
| 
 | |
| :marked
 | |
|   If you must guard against this kind of "provider corruption", *don't rely on a launch-time module's `providers`.*
 | |
| 
 | |
|   Load the module lazily if you can.
 | |
|   Angular gives a [lazy-loaded module](#q-lazy-loaded-module-provider-visibility) its own child injector.
 | |
|   The module's providers are visible only within the component tree created with this injector.
 | |
| 
 | |
|   If you must load the module eagerly, when the application starts,
 | |
|   ***provide the service in a component instead.***
 | |
| 
 | |
|   Continuing with the same example, suppose the components of a module truly require a private, custom `HttpBackend`.
 | |
| 
 | |
|   Create a "top component" that acts as the root for all of the module's components.
 | |
|   Add the custom `HttpBackend` provider to the top component's `providers` list rather than the module's `providers`.
 | |
|   Recall that Angular creates a child injector for each component instance and populates the injector
 | |
|   with the component's own providers.
 | |
| 
 | |
|   When a child of this component _asks_ for the `HttpBackend` service,
 | |
|   Angular provides the local `HttpBackend` service,
 | |
|   not the version provided in the application root injector.
 | |
|   Child components will make proper http requests no matter what other modules do to `HttpBackend`.
 | |
| 
 | |
|   Be sure to create module components as children of this module's top component.
 | |
| 
 | |
|   You can embed the child components in the top component's template.
 | |
|   Alternatively, make the top component a routing host by giving it a `<router-outlet>`.
 | |
|   Define child routes and let the router load module components into that outlet.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-root-component-or-module
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Should I add app-wide providers to the root _AppModule_ or the root _AppComponent_?
 | |
| 
 | |
| .alert.is-helpful
 | |
|   :marked
 | |
|     Register application-wide providers in the root `AppModule`, not in the `AppComponent`.
 | |
| :marked
 | |
|   Lazy-loaded modules and their components can inject `AppModule` services;
 | |
|   they cannot inject `AppComponent` services.
 | |
| 
 | |
|   Register a service in `AppComponent` providers _only_ if the service must be hidden
 | |
|   from components outside the `AppComponent` tree. This is a rare exceptional use case.
 | |
| 
 | |
|   More generally, [prefer registering providers in modules](#q-component-or-module) to registering in components.
 | |
| 
 | |
|   #### **_Discussion_:**
 | |
|   Angular registers all startup module providers with the application root injector.
 | |
|   The services created from root injector providers are available to the entire application.
 | |
|   They are _application-scoped_.
 | |
| 
 | |
|   Certain services (e.g., the `Router`) only work when registered in the application root injector.
 | |
| 
 | |
|   By contrast, Angular registers `AppComponent` providers with the `AppComponent`'s own injector.
 | |
|   `AppComponent`services are available only to that component and its component tree.
 | |
|   They are _component-scoped_.
 | |
| 
 | |
|   The `AppComponent`'s injector is a _child_ of the root injector, one down in the injector hierarchy.
 | |
|   That is _almost_ the entire application for apps that don't use the router.
 | |
|   But "almost" isn't good enough for routed applications.
 | |
| 
 | |
|   `AppComponent` services don't exist at the root level where routing operates.
 | |
|   Lazy loaded modules can't reach them.
 | |
|   In the Angular Module Chapter sample applications, if we had registered `UserService` in the `AppComponent`,
 | |
|   the `HeroComponent` couldn't inject it.
 | |
|   The application  would fail the moment a user navigated to "Heroes".
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-component-or-module
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Should I add other providers to a module or a component?
 | |
| 
 | |
|   In general, prefer registering feature-specific providers in modules (`@NgModule.providers`)
 | |
|   to registering in components (`@Component.providers`).
 | |
| 
 | |
|   Register a provider with a component when you _must_ limit the scope of a service instance
 | |
|   to that component and its component tree.
 | |
|   Apply the same reasoning to registering a provider with a directive.
 | |
| 
 | |
|   For example, a hero editing component that needs a private copy of a caching hero service should register
 | |
|   the `HeroService` with the `HeroEditorComponent`.
 | |
|   Then each new instance of the `HeroEditorComponent` gets its own cached service instance.
 | |
|   The changes that editor makes to heroes in its service do not touch the hero instances elsewhere in the application.
 | |
| 
 | |
|   [Always register _application-wide_ services with the root `AppModule`](q-root-component-or-module),
 | |
|   not the root `AppComponent`.
 | |
| 
 | |
| .l-hr
 | |
| a#q-why-bad
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Why is it bad if _SharedModule_ provides a service to a lazy loaded module?
 | |
| 
 | |
|   This question arose in the [Angular Module](../guide/ngmodule.html#no-shared-module-providers) chapter
 | |
|   when we discussed the importance of keeping providers out of the `SharedModule`.
 | |
| 
 | |
|   Suppose we had listed the `UserService` in the module's `providers` (which we did not).
 | |
|   Suppose every module imports this `SharedModule` (which they all do).
 | |
| 
 | |
|   When the app starts, Angular eagerly loads the `AppModule` and the `ContactModule`.
 | |
| 
 | |
|   Both instances of the imported `SharedModule` would provide the `UserService`.
 | |
|   Angular registers one of them in the root app injector (see [above](#q-reimport)).
 | |
|   Then some component injects `UserService`, Angular finds it in the app root injector,
 | |
|   and delivers the app-wide singleton `UserService`. No problem.
 | |
| 
 | |
|   Now consider the `HeroModule` _which is lazy loaded!_
 | |
| 
 | |
|   When the router lazy loads the `HeroModule`, it creates a child injector and registers the `UserService`
 | |
|   provider with that child injector. The child injector is _not_ the root injector.
 | |
| 
 | |
|   When Angular creates a lazy `HeroComponent`, it must inject a `UserService`.
 | |
|   This time it finds a `UserService` provider in the lazy module's _child injector_
 | |
|   and creates a _new_ instance of the `UserService`.
 | |
|   This is an entirely different `UserService` instance
 | |
|   than the app-wide singleton version that Angular injected in one of the eagerly loaded components.
 | |
| 
 | |
|   That's almost certainly a mistake.
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Prove it for yourself.
 | |
|     Run the <live-example name="ngmodule">live example</live-example>.
 | |
|     Modify the `SharedModule` so that it provides the `UserService` rather than the `CoreModule`.
 | |
|     Then toggle between the "Contact" and "Heroes" links a few times.
 | |
|     The username goes bonkers as the Angular creates a new `UserService` instance each time.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-why-child-injector
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Why does lazy loading create a child injector?
 | |
| 
 | |
|   Angular adds `@NgModule.providers` to the application root injector ... unless the module is lazy loaded.
 | |
|   Then it creates a _child injector_ and adds the module's providers to the child injector.
 | |
| 
 | |
|   This means that a module behaves differently depending on whether it is loaded during application start
 | |
|   or lazy loaded later. Neglecting that difference can lead to [adverse consequences](#q-why-bad).
 | |
| 
 | |
|   Why doesn't Angular add lazy loaded providers to the app root injector as it does for eagerly loaded modules?
 | |
|   Why the inconsistency?
 | |
| 
 | |
|   The answer is grounded in a fundamental characteristic of the Angular dependency injection system.
 | |
|   An injector can add providers _until it is first used_.
 | |
|   Once an injector starts creating and delivering services, its provider list is frozen. No new providers allowed.
 | |
| 
 | |
|   When an applications starts, Angular first configures the root injector with the providers of all eagerly loaded modules
 | |
|   _before_ creating its first component and injecting any of the provided services.
 | |
|   Once the application begins, the app root injector is closed to new providers.
 | |
| 
 | |
|   Time passes. Application logic triggers lazy loading of a module.
 | |
|   Angular must add the lazy loaded module's providers to an injector _somewhere_.
 | |
|   It can't added them to the app root injector because that injector is closed to new providers.
 | |
|   So Angular creates a new child injector for the lazy loaded module context.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-is-it-loaded
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### How can I tell if a module or service was previously loaded?
 | |
| 
 | |
|   Some modules and its services should only be loaded once by the root `AppModule`.
 | |
|   Importing the module a second time by lazy loading a module could [produce errant behavior](#q-why-bad)
 | |
|   that may be difficult to detect and diagnose.
 | |
| 
 | |
|   We can guard against that danger by writing a constructor that attempts to inject the module or service
 | |
|   from the root app injector. If the injection succeeds, the class has been loaded a second time.
 | |
|   We can throw an error or take other remedial action.
 | |
| 
 | |
|   Certain Angular modules (such as `BrowserModule`) implements such a guard
 | |
|   as does this Angular Module chapter sample's `CoreModule` constructor.
 | |
| +makeExample('ngmodule/ts/app/core/core.module.ts', 'ctor', 'app/core/core.module.ts (Constructor)')(format='.')
 | |
| :marked
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-entry-component-defined
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What is an _entry component_?
 | |
| 
 | |
|   Any component that Angular loads _imperatively_ by type is an _entry component_,
 | |
| 
 | |
|   A component loaded _declaratively_ via its selector is _not_ an entry component.
 | |
| 
 | |
|   Most application components are loaded declaratively.
 | |
|   Angular uses the component's selector to locate the element in the template.
 | |
|   It then creates the HTML representation of the component and inserts it into the DOM at the selected element.
 | |
|   These are not entry components.
 | |
| 
 | |
|   A few components are only loaded dynamically and are _never_ referenced in a component template.
 | |
| 
 | |
|   The bootstrapped root `AppComponent` is an _entry component_.
 | |
|   True, its selector matches an element tag in `index.html`.
 | |
|   But `index.html` is not a component template and the `AppComponent`
 | |
|   selector doesn't match an element in any component template.
 | |
| 
 | |
|   Angular loads `AppComponent` dynamically either because we listed it _by type_ in `@NgModule.bootstrap`
 | |
|   or because we boostrapped it imperatively with the module's `ngDoBootstrap` method.
 | |
| 
 | |
|   Components in route definitions are also _entry components_.
 | |
|   A route definition refers to a component by its _type_.
 | |
|   The router ignores a routed component's selector (if it even has one) and
 | |
|   loads the component dynamically into a `RouterOutlet`.
 | |
| 
 | |
|   The compiler can't discover these _entry components_ by looking for them in other component templates.
 | |
|   We must tell it about them ... by adding them to the `entryComponents` list.
 | |
| 
 | |
|   Angular automatically adds two kinds of components to the module's `entryComponents`:
 | |
|   1. the component in the `@NgModule.bootstrap` list
 | |
|   1. components referenced in router configuration
 | |
| 
 | |
|   We don't have to mention these components explicitly although it does not harm to do so.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-bootstrap_vs_entry_component
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What's the difference between a _bootstrap_ component and an _entry component_?
 | |
| 
 | |
|   A bootstrapped component _is_ an [entry component](#q-entry-component-defined).
 | |
|   It's an entry component that Angular loads into the DOM during the bootstrap (application launch) process.
 | |
|   Other entry components are loaded dynamically by other means such as with the router.
 | |
| 
 | |
|   The `@NgModule.bootstrap` property tells the compiler _both_ that this is an entry component _and_
 | |
|   that it should generate code to bootstrap the application with this component.
 | |
| 
 | |
|   There is no need to list a component in both the `bootstrap` and `entryComponent` lists
 | |
|   although it is harmless to do so.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-when-entry-components
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### When do I add components to _entryComponents_?
 | |
| 
 | |
|   Most application developers won't need to add components to the `entryComponents`.
 | |
| 
 | |
|   Angular adds certain components to _entry components_ automatically.
 | |
|   Components listed in `@NgModule.bootstrap` are added automatically.
 | |
|   Components referenced in router configuration are added automatically.
 | |
|   These two mechanisms account for almost all entry components.
 | |
| 
 | |
|   If your app happens to bootstrap or dynamically load a component _by type_ in some other manner,
 | |
|   you'll have to add it to `entryComponents` explicitly.
 | |
| 
 | |
|   Although it's harmless to add components to this list,
 | |
|   it's best to add only the components that are truly _entry components_.
 | |
|   Don't include components that [are referenced](#q-template-reference)
 | |
|   in the templates of other components.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-why-entry-components
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Why does Angular need _entryComponents_?
 | |
|   _Entry components_ are also declared.
 | |
|   Why doesn't the Angular compiler generate code for every component in `@NgModule.declarations`?
 | |
|   Then we wouldn't need entry components.
 | |
| 
 | |
|   The reason is _tree shaking_. For production apps we want to load the smallest, fastest code possible.
 | |
|   The code should contain only the classes that we actually need.
 | |
|   It should exclude a component that's never used, whether or not that component is declared.
 | |
| 
 | |
|   In fact, many libraries declare and export components we'll never use.
 | |
|   The _tree shaker_ will drop these components from the final code package
 | |
|   if we don't reference them.
 | |
| 
 | |
|   If the [Angular compiler](#q-angular-compiler) generated code for every declared component,
 | |
|   it would defeat the purpose of the tree shaker.
 | |
| 
 | |
|   Instead, the compiler adopts a recursive strategy that generates code only for the components we use.
 | |
| 
 | |
|   It starts with the entry components,
 | |
|   then it generates code for the declared components it [finds](#q-template-reference) in an entry component's template,
 | |
|   then for the declared components it discovers in the templates of previously compiled components,
 | |
|   and so on. At the end of the process, it has generated code for every  entry component
 | |
|   and every component reachable from an entry component.
 | |
| 
 | |
|   If a component isn't an _entry component_ or wasn't found in a template,
 | |
|   the compiler omits it.
 | |
| 
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-module-recommendations
 | |
| .l-main-section
 | |
| :marked
 | |
|   #### What kinds of modules should I have and how should I use them?
 | |
| 
 | |
|   Every app is different and developers have varying levels of experience and comfort with the available choices.
 | |
|   Some suggestions and guidelines appear to have wide appeal.
 | |
| 
 | |
| .alert.is-important
 | |
|   :marked
 | |
|     The following is preliminary guidance based on early experience using Angular modules in a few applications.
 | |
|     Read with appropriate caution and reflection.
 | |
| 
 | |
| :marked
 | |
|   #### _SharedModule_
 | |
|   Create a `SharedModule` with the components, directives, and pipes that you use
 | |
|   everywhere in your app. This module should consist entirely of `declarations`
 | |
|   most of them exported.
 | |
| 
 | |
|   It may re-export other [widget modules](#widget-feature-module) such as `CommonModule`,
 | |
|   `FormsModule` and modules with the UI controls that you use most widely.
 | |
| 
 | |
|   It should ***not*** have `providers` for reasons [explained earlier](#q-why-bad).
 | |
|   Nor should any of its imported or re-exported modules have `providers`.
 | |
|   Know what you're doing and why if you deviate from this guideline.
 | |
| 
 | |
|   Import the `SharedModule` in your _feature_ modules,
 | |
|   both those loaded when the app starts and those you lazy load later.
 | |
| 
 | |
|   #### _CoreModule_
 | |
|   Create a `CoreModule` with `providers` for the singleton services you load when the application starts.
 | |
| 
 | |
|   Import `CoreModule` in the root `AppModule` only.
 | |
|   Never import `CoreModule` in any module other than the root `AppModule`.
 | |
| 
 | |
|   Consider making `CoreModule` a [pure services module](#service-feature-module) with no `declarations`.
 | |
| 
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     This chapter sample departs from that advice by declaring and exporting two components that are
 | |
|     only used within the root `AppComponent` declared by `AppModule`.
 | |
|     Someone following this guideline strictly would have declared these components in the `AppModule` instead.
 | |
| 
 | |
| :marked
 | |
|   #### Feature Modules
 | |
|   Create _Feature Modules_ around specific application business domains, user workflows, and utility collections.
 | |
| 
 | |
|   Feature modules tend to fall into one of these four groups:
 | |
|     * [Domain Feature Modules](#domain-feature-module)
 | |
|     * [Routed Feature Modules](#routed-feature-module)
 | |
|     * [Routing Modules](#routing-module)
 | |
|     * [Service Feature Modules](#service-feature-module)
 | |
|     * [Widget Feature Modules](#widget-feature-module)
 | |
| 
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Real world modules are often hybrids that knowingly deviate from the following guidelines.
 | |
|     They are guidelines, not laws.
 | |
|     Follow them until you have a good reason to do otherwise.
 | |
| 
 | |
| table
 | |
|   tr
 | |
|     th(style="vertical-align: top") Feature Module
 | |
|     th(style="vertical-align: top") Guidelines
 | |
|   tr
 | |
|     td(style="vertical-align: top")<a id="domain-feature-module"></a>Domain
 | |
|     td
 | |
|       :marked
 | |
|         Domain Feature Modules deliver a user experience **dedicated to a particular application domain**
 | |
|         like editing a customer or placing an order.
 | |
| 
 | |
|         They typically have a top component that acts as the feature root.
 | |
|         Private, supporting sub-components descend from it.
 | |
| 
 | |
|         Domain feature module consist mostly of _declarations_.
 | |
|         Only the top component is exported.
 | |
| 
 | |
|         Domain feature modules rarely have _providers_.
 | |
|         When they do, the lifetime of the provided services
 | |
|         should be the same as the lifetime of the module.
 | |
| 
 | |
|         Do not provide application-wide singleton services in a domain feature module.
 | |
| 
 | |
|         Domain feature modules are typically imported _exactly once_ by a larger feature module.
 | |
| 
 | |
|         They might be imported by the root `AppModule` of a small application that lacks routing.
 | |
| 
 | |
|       .l-sub-section
 | |
|         :marked
 | |
|           For an example, see [_ContactModule_](../guide/ngmodule.html#contact-module-v1)
 | |
|           in the Angular Module chapter, before we introduced routing.
 | |
|   tr
 | |
|     td(style="vertical-align: top")<a id="routed-feature-module"></a>Routed
 | |
|     td
 | |
|       :marked
 | |
|         _Routed Feature Modules_ are _Domain Feature modules_
 | |
|         whose top components are the **targets of router navigation routes**.
 | |
| 
 | |
|         All lazy loaded modules are routed feature modules by definition.
 | |
| 
 | |
|         This chapter's `ContactModule`, `HeroModule` and `CrisisModule` are routed feature modules.
 | |
| 
 | |
|         Routed Feature Modules _should not export anything_.
 | |
|         They don't have to because none of their components ever appear in the template of an external component.
 | |
| 
 | |
|         A lazy loaded Routed Feature Module should _not be imported_ by any module.
 | |
|         Doing so would trigger an eager load, defeating the purpose of lazy loading.
 | |
|         `HeroModule` and `CrisisModule` are lazy loaded. They aren't mentioned among the `AppModule` imports.
 | |
| 
 | |
|         But an eager loaded Routed Feature Module must be imported by another module
 | |
|         so that the compiler learns about its components.
 | |
|         `ContactModule` is eager loaded and, therefore, is listed among the `AppModule` imports.
 | |
| 
 | |
|         Routed Feature Modules rarely have _providers_ for reasons [explained earlier](#q-why-bad).
 | |
|         When they do, the lifetime of the provided services
 | |
|         should be the same as the lifetime of the module.
 | |
| 
 | |
|         Do not provide application-wide singleton services in a routed feature module
 | |
|         or in a module that the routed module imports.
 | |
|   tr
 | |
|     td(style="vertical-align: top")<a id="routing-module"></a>Routing
 | |
|     td
 | |
|       :marked
 | |
|         A [_Routing Module_](../guide/router.html#routing-module) **provides routing configuration** for another module.
 | |
| 
 | |
|         A Routing Module separates routing concerns from its companion module.
 | |
|         
 | |
|         It typically:
 | |
|         * defines routes
 | |
|         * adds router configuration to the module's `imports`
 | |
|         * re-exports `RouterModule`
 | |
|         * adds guard and resolver service providers to the module's `providers`.
 | |
|         
 | |
|         The name of the Routing Module should parallel the name of its companion module, using the suffix "Routing".
 | |
|         For example, `FooModule` in `foo.module.ts` has a routing module named `FooRoutingModule`
 | |
|         in `foo-routing.module.ts`
 | |
|         
 | |
|         If the companion module is the _root_ `AppModule`, 
 | |
|         the `AppRoutingModule` adds router configuration to its `imports` with `RouterModule.forRoot(routes)`. 
 | |
|         All other Routing Modules are children that import `RouterModule.forChild(routes)`.
 | |
| 
 | |
|         A Routing Module re-exports the `RouterModule` as a convenience 
 | |
|         so that components of the companion module have access to 
 | |
|         router directives such as `RouterLink` and `RouterOutlet`.
 | |
| 
 | |
|         A Routing Module **should not have its own `declarations`!** 
 | |
|           Components, directives, and pipes are the **responsibility of the feature module**
 | |
|         not the _routing_ module.
 | |
| 
 | |
|         A Routing Module should _only_ be imported by its companion module.
 | |
| 
 | |
|         The `AppRoutingModule`, `ContactRoutingModule` and `HeroRoutingModule` are good examples.
 | |
|       .l-sub-section
 | |
|         :marked
 | |
|           See also "[Do you need a _Routing Module_?](../guide/router.html#why-routing-module)".
 | |
| 
 | |
|   tr
 | |
|     td(style="vertical-align: top")<a id="service-feature-module"></a>Service
 | |
|     td
 | |
|       :marked
 | |
|         _Service Modules_ **provide utility services** such as data access and messaging.
 | |
| 
 | |
|         Ideally they consist entirely of _providers_ and have no _declarations_.
 | |
|         The `CoreModule` and Angular's `HttpModule` are good examples.
 | |
| 
 | |
|         Service Modules should _only_ be imported by the root `AppModule`.
 | |
| 
 | |
|         Do **not** import them in other feature modules.
 | |
|         Know what you're doing and why if you deviate from this guideline.
 | |
|   tr
 | |
|     td(style="vertical-align: top")<a id="widget-feature-module"></a>Widget
 | |
|     td
 | |
|       :marked
 | |
|         A _Widget Module_ makes **components, directives, and pipes** available to external modules.
 | |
| 
 | |
|         `CommonModule` and `SharedModule` are widget modules.
 | |
|         Many third party UI component libraries are widget modules.
 | |
| 
 | |
|         A Widget Module should consist entirely of _declarations_, most of them exported.
 | |
| 
 | |
|         A Widget Module should rarely have _providers_.
 | |
|         Know what you're doing and why if you deviate from this guideline.
 | |
| 
 | |
|         Import Widget Modules in any module whose component templates need the widgets.
 | |
| 
 | |
| :marked
 | |
|   The following table summarizes the key characteristics of each _Feature Module_ group.
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Real world modules are often hybrids that knowingly deviate from these guidelines.
 | |
| table
 | |
|   tr
 | |
|     th Feature Module
 | |
|     th Declarations
 | |
|     th Providers
 | |
|     th Exports
 | |
|     th Imported By
 | |
|     th Examples
 | |
|   tr
 | |
|     td Domain
 | |
|     td Yes
 | |
|     td Rare
 | |
|     td Top Component
 | |
|     td Feature, <code>AppModule</code>
 | |
|     td <code>ContactModule</code> (before routing)
 | |
|   tr
 | |
|     td Routed
 | |
|     td Yes
 | |
|     td Rare
 | |
|     td No
 | |
|     td Nobody
 | |
|     td <code>ContactModule</code>, <code>HeroModule</code>, <code>CrisisModule</code>
 | |
|   tr
 | |
|     td Routing
 | |
|     td No
 | |
|     td Yes (Guards)
 | |
|     td <code>RouterModule</code>
 | |
|     td Feature (for routing)
 | |
|     td <code>AppRoutingModule</code>, <code>ContactRoutingModule</code>, <code>HeroRoutingModule</code>
 | |
|   tr
 | |
|     td Service
 | |
|     td No
 | |
|     td Yes
 | |
|     td No
 | |
|     td <code>AppModule</code>
 | |
|     td <code>HttpModule</code>, <code>CoreModule</code>
 | |
|   tr
 | |
|     td Widget
 | |
|     td Yes
 | |
|     td Rare
 | |
|     td Yes
 | |
|     td Feature
 | |
|     td <code>CommonModule</code>, <code>SharedModule</code>
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-ng-vs-js-modules
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What's the difference between Angular and JavaScript Modules?
 | |
| 
 | |
|   Angular and JavaScript are two different yet complementary module systems.
 | |
| 
 | |
|   In modern JavaScript, [every file is a _module_](http://exploringjs.com/es6/ch_modules.html).
 | |
|   Within each file we write an `export` statement to make parts of the module public:
 | |
| 
 | |
| code-example(format='.').
 | |
|   export class AppComponent { ... }
 | |
| 
 | |
| :marked
 | |
|   Then we `import` a part in another module:
 | |
| 
 | |
| code-example(format='.').
 | |
|   import { AppComponent }  from './app.component';
 | |
| 
 | |
| :marked
 | |
|   This kind of modularity is a feature of the _JavaScript language_.
 | |
| 
 | |
|   An _Angular Module_ is a feature of _Angular_ itself.
 | |
| 
 | |
|   Angular's `NgModule` also has `imports` and `exports` and they serve a similar purpose.
 | |
| 
 | |
|   We _import_ other Angular modules so we can use their exported classes in component templates.
 | |
|   We _export_ this Angular module's classes so they can be imported and used by components of _other_ modules.
 | |
| 
 | |
|   The Angular module classes differ from JavaScript module class in three key respects:
 | |
| 
 | |
|   1. An Angular module bounds [_declarable classes_](#q-declarables) only.
 | |
|   Declarables are the only classes that matter to the [Angular compiler](#q-angular-compiler).
 | |
| 
 | |
|   1. Instead of defining all member classes in one giant file (as in a JavaScript module),
 | |
|      we list the module's classes in the `@NgModule.declarations` list.
 | |
| 
 | |
|   1. An Angular module can only export the [_declarable classes_](#q-declarables)
 | |
|   it owns or imports from other modules.
 | |
|   It doesn't declare or export any other kind of class.
 | |
| 
 | |
|   The Angular Module is also special in another way.
 | |
|   Unlike JavaScript modules, an Angular module can extend the _entire_ application with services
 | |
|   by adding providers to the `@NgModule.providers` list.
 | |
| 
 | |
| .alert.is-important
 | |
|   :marked
 | |
|     The provided services do not belong to the module nor are they scoped to the declared classes.
 | |
|     They are available _everywhere_.
 | |
| 
 | |
| :marked
 | |
|   Here's an _Angular Module_ class with imports, exports, and declarations.
 | |
| +makeExample('ngmodule/ts/app/contact/contact.module.2.ts', 'class')(format=".")
 | |
| :marked
 | |
|   Of course we use _JavaScript_ modules to write _Angular_ modules as seen in the complete `contact.module.ts` file:
 | |
| +makeExample('ngmodule/ts/app/contact/contact.module.2.ts', '', 'app/contact/contact.module.ts')(format=".")
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-template-reference
 | |
| .l-main-section
 | |
| h4.
 | |
|   How does Angular find components, directives, and pipes in a template?<br>What is a <i><b>template reference</b></i>?
 | |
| :marked
 | |
|   The [Angular compiler](#q-angular-compiler) looks inside component templates
 | |
|   for other components, directives, and pipes. When it finds one, that's a "template reference".
 | |
| 
 | |
|   The Angular compiler finds a component or directive in a template when it can match the **selector** of that
 | |
|   component or directive to some HTML in that template.
 | |
| 
 | |
|   The compiler finds a pipe if the pipe's **name** appears within the pipe syntax of the template HTML.
 | |
| 
 | |
|   Angular only matches selectors and pipe names for classes that are declared by this module
 | |
|   or exported by a module that this module imports.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-angular-compiler
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### What is the Angular Compiler?
 | |
| 
 | |
|   The _Angular Compiler_ converts the application code we write into highly performant JavaScript code.
 | |
|   The `@NgModule` metadata play an important role in guiding the compilation process.
 | |
| 
 | |
|   The code we write is not immediately executable.
 | |
|   Consider **components**.
 | |
|   Components have templates that contain custom elements, attribute directives, Angular binding declarations,
 | |
|   and some peculiar syntax that clearly isn't native HTML.
 | |
| 
 | |
|   The _Angular Compiler_ reads the template markup,
 | |
|   combines it with the corresponding component class code, and emits _component factories_.
 | |
| 
 | |
|   A component factory creates a pure, 100% JavaScript representation
 | |
|   of the component that incorporates everything described in its `@Component` metadata:
 | |
|   the HTML, the binding instructions, the attached styles ... everything.
 | |
| 
 | |
|   Because **directives** and **pipes** appear in component templates,
 | |
|   the _Angular Compiler_ incorporates them into compiled component code too.
 | |
| 
 | |
|   `@NgModule` metadata tells the _Angular Compiler_ what components to compile for this module and
 | |
|   how to link this module with other modules.
 | |
| 
 | |
| .l-hr
 | |
| 
 | |
| a#q-ngmodule-api
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## *NgModule* API
 | |
| 
 | |
|   The following chart summarizes the `NgModule` metadata properties.
 | |
| //
 | |
|   export interface NgModuleMetadataType {
 | |
|     providers?: any[];
 | |
|     declarations?: Array<Type|any[]>;
 | |
|     imports?: Array<Type|ModuleWithProviders|any[]>;
 | |
|     exports?: Array<Type|any[]>;
 | |
|     entryComponents?: Array<Type|any[]>;
 | |
|     bootstrap?: Array<Type|any[]>;
 | |
|     schemas?: Array<SchemaMetadata|any[]>;
 | |
|   }
 | |
| 
 | |
| table
 | |
|   tr
 | |
|     th Property
 | |
|     th Description
 | |
|   tr
 | |
|     td(style="vertical-align: top") <code>declarations</code>
 | |
|     td
 | |
|       :marked
 | |
|         A list of [declarable](#q-declarables) classes,
 | |
|         the **component**, **directive** and **pipe** classes that _belong to this module_.
 | |
| 
 | |
|         These declared classes are visible within the module but invisible to
 | |
|         components in a different module unless (a) they are _exported_ from this module and
 | |
|         (b) that other module _imports_ this one.
 | |
| 
 | |
|         Components, directives and pipes must belong to _exactly_ one module.
 | |
|         The compiler emits an error if we try to declare the same class in more than one module.
 | |
| 
 | |
|         **Do not re-declare a class imported from another module.**
 | |
| 
 | |
|   tr
 | |
|     td(style="vertical-align: top") <code>providers</code>
 | |
|     td
 | |
|       :marked
 | |
|         A list of dependency injection providers.
 | |
| 
 | |
|         Angular registers these providers with the root injector of the module's execution context.
 | |
|         That's the application's root injector for all modules loaded when the application starts.
 | |
| 
 | |
|         Angular can inject one of these provider services into any component in the application.
 | |
|         If this module provides the `HeroService`, or any module loaded at launch provides the `HeroService`,
 | |
|         Angular can inject the same `HeroService` intance into any app component.
 | |
| 
 | |
|         A lazy loaded module has its own sub-root injector which typically
 | |
|         is a direct child of the application root injector.
 | |
| 
 | |
|         Lazy loaded services are scoped to the lazy module's injector.
 | |
|         If a lazy loaded module also provides the `HeroService`,
 | |
|         any component created within that module's context (e.g., by router navigation)
 | |
|         gets the local instance of the service, not the instance in the root application injector.
 | |
| 
 | |
|         Components in external modules continue to receive the instance created for the application root.
 | |
| 
 | |
|   tr
 | |
|     td(style="vertical-align: top") <code>imports</code>
 | |
|     td
 | |
|       :marked
 | |
|         A list of supporting modules.
 | |
| 
 | |
|         Specifically, the list of modules whose exported components, directives or pipes
 | |
|         are referenced by the component templates declared in this module.
 | |
| 
 | |
|         A component template can [reference](#q-template-reference) another component, directive or pipe
 | |
|         on two conditions: either the referenced class is declared in this module
 | |
|         or the class was imported from another module.
 | |
| 
 | |
|         A component can use the `NgIf` and `NgFor` directives only because its parent module
 | |
|         imported the Angular `CommonModule` (perhaps indirectly by importing `BrowserModule`).
 | |
| 
 | |
|         We can import many standard directives with the `CommonModule`.
 | |
|         But some familiar directives belong to other modules.
 | |
|         A component template can bind with `[(ngModel)]` only after importing the Angular `FormsModule`.
 | |
|   tr
 | |
|     td(style="vertical-align: top") <code>exports</code>
 | |
|     td
 | |
|       :marked
 | |
|         A list of declarations — **component**, **directive**, and **pipe** classes — that
 | |
|         an importing module can use.
 | |
| 
 | |
|         Exported declarations are the module's _public API_.
 | |
|         A component in another module can [reference](#q-template-reference) _this_ module's `HeroComponent`
 | |
|         if (a) it imports this module and (b) this module exports `HeroComponent`.
 | |
| 
 | |
|         Declarations are private by default.
 | |
|         If this module does _not_ export `HeroComponent`, no other module can see it.
 | |
| 
 | |
|         Importing a module does _not_ automatically re-export the imported module's exports.
 | |
|         Module 'B' can't use `ngIf` just because it imported module `A` which imported `CommonModule`.
 | |
|         Module 'B' must import `CommonModule` itself.
 | |
| 
 | |
|         A module can list another module among its `exports` in which case
 | |
|         all of that module's public components, directives, and pipes are exported.
 | |
| 
 | |
|         [Re-export](#q-re-export) makes module transitivity explicit.
 | |
|         If Module 'A' re-exports `CommonModule` and Module 'B' imports Module 'A',
 | |
|         Module 'B' components can use `ngIf` even though 'B' itself didn't import `CommonModule`.
 | |
| 
 | |
|   tr
 | |
|     td(style="vertical-align: top") <code>bootstrap</code>
 | |
|     td
 | |
|       :marked
 | |
|         A list of components that can be bootstrapped.
 | |
| 
 | |
|         Usually there is only one component in this list, the _root component_ of the application.
 | |
| 
 | |
|         Angular can launch with multiple bootstrap components,
 | |
|         each with its own location in the host web page.
 | |
| 
 | |
|         A bootstrap component is automatically an `entryComponent`
 | |
| 
 | |
|   tr
 | |
|     td(style="vertical-align: top") <code>entryComponents</code>
 | |
|     td
 | |
|       :marked
 | |
|         A list of components that are _not_ [referenced](#q-template-reference) in a reachable component template.
 | |
| 
 | |
|         Most developers will never set this property. Here's why.
 | |
| 
 | |
|         The [_Angular Compiler_](#q-angular-compiler) must know about every component actually used in the application.
 | |
|         The compiler can discover most components by walking the tree of references
 | |
|         from one component template to another.
 | |
| 
 | |
|         But there's always at least one component that is not referenced in any template:
 | |
|         the root component, `AppComponent`, that we bootstrap to launch the app.
 | |
|         That's why it's called an _entry component_.
 | |
| 
 | |
|         Routed components are also _entry components_ because they aren't referenced in a template either.
 | |
|         The router creates them and drops them into the DOM near a `<router-outlet>`.
 | |
| 
 | |
|         While the bootstrapped and routed components are _entry components_,
 | |
|         we usally don't have to add them to a module's `entryComponents` list.
 | |
| 
 | |
|         Angular automatically adds components in the module's `bootstrap` list to the `entryComponents` list.
 | |
|         The `RouterModule` adds routed components to that list.
 | |
| 
 | |
|         That leaves only two sources of undiscoverable components.
 | |
|         1. Components bootstrapped using one of the imperative techniques.
 | |
|         1. Components dynamically loaded into the DOM by some means other than the router.
 | |
| 
 | |
|         Both are advanced techniques that few developers will ever employ.
 | |
|         If you are one of those few, you'll have to add these components to the
 | |
|         `entryComponents` list yourself, either programmatically or by hand.
 |