ANGULAR2 multistage Injector and Example _angularjs

Source: Internet
Author: User
Tags constructor documentation export class

ANGULAR2 's dependency injection contains too much content, one of the key points is the injector, and the injector is very difficult to understand, today we do not delve into the contents of the injector, we can refer to the official documentation, we are today the level of the injector.

That is, the container in which the component gets the service chooses which one to specify.

Let's briefly introduce a background: There are 3 components appcomponent root components, detaillist components (log list components), detail components (log components).

These three components form a tree of components, and we can also assume that each component will have a separate injector (sometimes not, but you can think so).

Join a log service Loggerservice, providing loggerservice in the root module providers, as we normally get started. So in the entire application, Loggerservice has only one instance, what does it mean? That is to say, no matter what component you get is the first created loggerservice, all components share a service instance, which can be a useful feature, such as the global configuration we use.

The whole thing is not the focus of our verification this time, because this is too common, and we're going to show you how we can get a separate Loggerservice instance in each component, which is different for each component instance. This requires an understanding of NG2 's dependency injection.

How do we go about implementing this step-by-step?

To make it easier for the students to see this passage, I added some basic code.

1.app.module.ts application root module. Note that we do not register loggerservice here in providers. Of course the registration through the back of the method can also achieve our goal.

Import {ngmodule, Optional, Skipself, reflectiveinjector} from ' @angular/core ';

Import {Browsermodule} from ' @angular/platform-browser ';
/* APP Root */import {appcomponent} from './app.component ';
Import {routing} from './app.routing ';
Import {Title} from ' @angular/platform-browser ';
Import {messagesmodule, growlmodule, Buttonmodule}from ' Primeng/primeng ';
Import {appdetailcomponent}from './app-detail.component ';
Import {appdetaillistcomponent}from './app-detaillist.component ';
Import {loggerservice}from './logger.service ';

Let alltitle:string= "Guo Zhiqi"; @NgModule ({imports: [Browsermodule, Messagesmodule, Growlmodule, Buttonmodule], declarations: [Appcomponent, APPD Etailcomponent, appdetaillistcomponent],//declares the specified component information required by the current module exports: [], providers: [Title], Bootstrap: [Appcomponent]}
 ) Export class Appmodule {constructor (@Optional () @SkipSelf () parentmodule:appmodule) {console.log (parentmodule); if (parentmodule) {throw new Error (' Appmodule is already loaded.
 Import it in the Appmodule only '); }
 }
}

2.app.component.ts Application root Component

Import {Component, viewencapsulation, Host, Viewcontainerref, reflectiveinjector} from ' @angular/core ';
Import {Title} from ' @angular/platform-browser ';
Import {message} from ' Primeng/primeng ';
Import {loggerservice}from './logger.service ';
@Component ({
 selector: ' My-app ',
 moduleId:module.id,
 templateurl: './app.component.html '
 , Providers: [
  {provide:loggerservice, useclass:loggerservice}
 ]
})
Export class Appcomponent { C14/>subtitle = ' (Final) ';
 Private msgs:message[];
 Constructor (private Title:title, @Host () private Logger:loggerservice) {
  this.title.setTitle ("appcomponent"); c18/>} show

 (): void {
  this.logger.Debug ();
 }
}

Please note that we have registered loggerservice in the providers with the component.

The 3.app.detaillist.ts log list is also registered in providers Loggerservice

Import {Component, host}from ' @angular/core ';
Import {loggerservice}from './logger.service ';

@Component ({
 selector: ' My-detaillist ',
 templateurl: './app-detaillist.component.html ',
 ModuleID: Module.id,
 providers: [
  {provide:loggerservice, useclass:loggerservice}
 ]
})

Export class appdetaillistcomponent {
 constructor (private Logger:loggerservice) {

 } show
 (): void {
  This.logger.Debug ();
 }

The 4.app.detail.ts log component providers is not registered Loggerservice.

Import {Component, host}from ' @angular/core ';
Import {loggerservice}from './logger.service ';
@Component ({
 selector: ' Detail ',
 moduleId:module.id,
 templateurl: './app-detail.component.html ',
 providers: [
  //{provide:loggerservice, useclass:loggerservice}
 ]
})

Export class appdetailcomponent {
 constructor (private Logger:loggerservice) {

 } show
 (): void {
  This.logger.Debug ();
 }

Now let's take a look at Loggerservice's hierarchical relationships through chrome.

By looking at the dependency graph, we can see that the Appcomponent component uses a separate loggerservice,detaillist component and a separate Loggerservice instance. The detail component uses a Loggerservice instance of the parent component detaillist.

At present, we do not meet our requirements, our requirement is that each component has a separate Loggerservice instance, then we assume that the detail component providers is we forget to input, it is difficult to test the cause. So let's add a @host () to limit the scope of the injector search.

Refer to the official documentation for the way the injector is looking up.

For ease of debugging, we add @host ().

@Host adorner will end up searching on the host component

Detail.ts prompts detail component to add @host () adorner

Import {Component, host}from ' @angular/core ';
Import {loggerservice}from './logger.service ';
@Component ({
 selector: ' Detail ',
 moduleId:module.id,
 templateurl: './app-detail.component.html ',
 providers: [
  //{provide:loggerservice, useclass:loggerservice}
 ]
})

Export class appdetailcomponent {
 Constructor (@Host () private Logger:loggerservice) {

 } show
 (): void {
  This.logger.Debug ();
 }

You will be prompted not to find an instance of Loggerservice, @Host () is to restrict the injector from finding the current component to stop and not to continue looking up. Therefore, there will be no providers error found.

Plus providers's result is what we want.

A perfect solution to the problem of multiple components using a single service instance.

Summary:

1. If you want the component to use the service separately, first register the service separately in providers. It's easy to understand.

2. To better detect possible problems, add the @host () adorner to the component service to throw the error message as early as possible

3. Use the Ng2 Debug tool

4. Be clear about the relationships between the components, because different component relationships can cause different instances of the service

5. The service is as far as module level, not application level.

Thank you for reading, I hope to help you, thank you for your support for this site!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.