ANGULAR2 Tips-multistage Injector

Source: Internet
Author: User
Tags export class

ANGULAR2 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 content of the injector, you can refer to the official documentation, we today to the level of the injector.

That is, the container that gets the service for the component chooses which one is specific.

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

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

Add a log service Loggerservice, and if you follow our normal introductory approach, provide loggerservice in the root module providers. So in the whole application, Loggerservice has only one instance, what does that mean? This means that regardless of which component is being acquired, the Loggerservice is created for the first time, and all components share a service instance, which can sometimes be a useful feature, such as the global configuration we use.

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

Let's step up to show how it's achieved.

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

1.app.module.ts the application root module. Note here that we did not register loggerservice in providers. Of course registered through the following methods can also achieve our purpose.

1Import {ngmodule, Optional, Skipself, reflectiveinjector} from ' @angular/core ';2Import {Browsermodule} from ' @angular/platform-browser ';3 4 /*App Root*/5Import {AppComponent} from './app.component ';6Import {routing} from './app.routing ';7Import {Title} from ' @angular/platform-browser ';8Import {messagesmodule, growlmodule, Buttonmodule}from ' Primeng/primeng ';9Import {appdetailcomponent}from './app-detail.component ';TenImport {appdetaillistcomponent}from './app-detaillist.component '; OneImport {loggerservice}from './logger.service '; ALet alltitle:string= "Guo Zhiqi"; -  - @NgModule ({ the imports: [ - Browsermodule, - Messagesmodule, - Growlmodule, Buttonmodule +   ], -declarations: [AppComponent, Appdetailcomponent, Appdetaillistcomponent],//declares the specified component information required by the current module + exports: [], A providers: [Title], at Bootstrap: [AppComponent] - }) - Export class Appmodule { - Constructor (@Optional () @SkipSelf () parentmodule:appmodule) { - Console.log (parentmodule); -     if(parentmodule) { in       Throw NewError ( -' Appmodule is already loaded. Import it in the Appmodule only '); to     } +   } -}

2.app.component.ts Application root Component

1Import {Component, viewencapsulation, Host, Viewcontainerref, reflectiveinjector} from ' @angular/core ';2Import {Title} from ' @angular/platform-browser ';3Import {Message} from ' Primeng/primeng ';4Import {loggerservice}from './logger.service ';5 @Component ({6Selector: ' My-app ',7 ModuleId:module.id,8Templateurl: './app.component.html ',9 providers: [Ten {provide:loggerservice, useclass:loggerservice} One     ] A }) - Export class AppComponent { -Subtitle = ' (Final) '; the private msgs:message[]; - Constructor (Private Title:title, @Host () private Logger:loggerservice) { -          This. Title.settitle ("AppComponent"); -     } +  -Show ():void { +          This. Logger. Debug (); A     } at}

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

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

Import {Component, host}from ' @angular/core './logger.service '; @Component ({    ' my-detaillist ') ,    './app-detaillist.component.html ',    moduleId:module.id,    providers: [        {provide: Loggerservice, Useclass:loggerservice}    ]}) Export class Appdetaillistcomponent {    constructor (   Private Logger:loggerservice) {    }    void  {        this. Logger. Debug ();}    }

4.app.detail.ts Log component providers is not registered Loggerservice.

1Import {Component, host}from ' @angular/core ';2Import {loggerservice}from './logger.service ';3 @Component ({4Selector: ' Detail ',5 ModuleId:module.id,6Templateurl: './app-detail.component.html ',7 providers: [8       //{provide:loggerservice, useclass:loggerservice}9     ]Ten }) One  A Export class Appdetailcomponent { - Constructor (private Logger:loggerservice) { -  the     } -Show ():void { -          This. Logger. Debug (); -     } +  -}

Now let's look at the hierarchical relationship of loggerservice 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 this point, we do not meet our requirements, our requirement is that each component has a separate Loggerservice instance, then we assume that the providers of the detail component is something we forgot to enter and it is difficult to test the reason. Then we add a @host () to limit the scope of the injector's search.

For an upward lookup of the injector, refer to the official documentation.

For ease of commissioning, we added @host ().

@HostThe adorner will cut the behavior of the search to the host component

DETAIL.TS Hint Detail component add @host () adorner

1Import {Component, host}from ' @angular/core ';2Import {loggerservice}from './logger.service ';3 @Component ({4Selector: ' Detail ',5 ModuleId:module.id,6Templateurl: './app-detail.component.html ',7 providers: [8       //{provide:loggerservice, useclass:loggerservice}9     ]Ten }) One  A Export class Appdetailcomponent { - Constructor (@Host () private Logger:loggerservice) { -  the     } -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 will not continue looking up. Therefore, there will be no providers errors found.

The result of adding providers is what we want.

A perfect solution to the problem of using separate service instances for multiple components.

Summarize:

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

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

3. Using the Ng2 Debug tool

4. To identify the relationships between the components, because different component relationships can cause different instances of the service

5. The service is as much as the module level, not the application level.

Angular2, a thing worth learning.

ANGULAR2 Tips-multistage Injector

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.