English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
angular2 A injeção de dependência contém muitos conteúdos, um dos pontos focais é o injetor, e o injetor é muito difícil de entender. Hoje não vamos introduzir em profundidade o conteúdo do injetor, você pode referir-se ao documento oficial, hoje vamos falar sobre a hierarquia do injetor.
isto é, o container de serviço do componente escolherá qual.
Primeiro, vamos fazer uma breve introdução de um contexto: há3Os componentes são AppComponent (componente raiz), DetailList (componente de lista de logs), Detail (componente de log).
Esses três componentes formam uma árvore de componentes, e podemos considerar que cada componente terá um injetor independente (às vezes não aparecerá, mas podemos considerar isso).
Adicione um serviço de log LoggerService, se seguirmos a maneira convencional de entrada, fornecer LoggerService nos providers do módulo raiz. Então, em todo o aplicativo, o LoggerService terá apenas uma instância, o que significa que, independentemente de qual componente, o que obteremos será o LoggerService criado pela primeira vez, todos os componentes compartilham uma instância de serviço. Isso às vezes pode ser uma característica útil, como a configuração global que usamos.
Globalmente único não é o ponto focal da nossa verificação dessa vez, pois é muito comum. O que vamos explicar é como obtermos uma instância separada do LoggerService em cada componente, ou seja, cada instância do componente é diferente. Isso requer uma compreensão da ng2do injecção de dependência.
Vamos explicar passo a passo como implementar?
Para facilitar a compreensão dos colegas que lerão este breve texto, adicionei alguns códigos básicos.
1.app.module.ts Aplicativo raiz do módulo. Observe que não registramos o loggerService nos Providers. Claro, podemos alcançar nosso objetivo através de métodos posteriores.
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="郭志奇"; @NgModule({ imports: [ BrowserModule, MessagesModule, GrowlModule, ButtonModule ], declarations: [AppComponent, AppDetailComponent, AppDetailListComponent],//Declarar informações de componentes específicos necessários pelo módulo atual exports: [], providers: [Title], bootstrap: [AppComponent] } export class AppModule { constructor( @Optional() @SkipSelf() parentModule: AppModule) { console.log(parentModule); if (parentModule) { throw new Error( 'O AppModule já está carregado. Importe-o apenas no AppModule'); } } }
2.app.component.ts - Componente raiz da aplicação
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 { subtitle = '(Final)'; private msgs: Message[]; constructor(private title: Title, @Host() private logger: LoggerService) { this.title.setTitle("AppComponent"); } show(): void { this.logger.Debug(); } }
Atenção, registramos LoggerService nos providers do componente raiz.
3.app.detailList.ts - LoggerService também foi registrado nos providers da lista de logs.
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(); } }
4.app.detail.ts - O componente de log não registrou LoggerService nos providers.
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(); } }
Agora, vamos usar o chrome para ver a relação hierárquica do LoggerService.
Através do gráfico de dependência, podemos ver que o componente AppComponent usa uma instância separada de LoggerService, o componente DetailList também usa uma instância de LoggerService, enquanto o componente Detail usa a instância de LoggerService do componente pai DetailList.
Pelo que parece, não atingimos nossos requisitos. Nossos requisitos são que cada componente tenha uma instância separada de LoggerService. Assim, suponhamos que os providers do componente Detail foram omitidos, dificultando a identificação da causa. Então, adicionamos um @Host() para limitar o escopo de busca do injetor.
Para a forma de busca ascendente do injetor, consulte o documento oficial.
Para facilitar o debugging, adicionamos @Host().
O decorador @Host() limita a busca para o componente anfitrião
detail.ts indica que o componente detail foi adicionado com o decorador @Host()
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(); } }
Será notificado que não foi possível encontrar a instância LoggerService, a função do @Host() é limitar o injetor a encontrar o componente atual e parar, não continuar para cima. Portanto, pode ocorrer o erro de não encontrar Providers.
Com o resultado de providers, temos o que queremos.
Perfeitamente resolveu o problema de uso de instâncias de serviços separados por componentes múltiplos.
Resumo:
1.Se desejar que o componente use o serviço sozinho, primeiro registre o serviço separadamente em providers. É fácil entender
2.Para melhor detectar possíveis problemas, adicione o decorador @Host() ao serviço de componente, o que pode lançar informações de erro mais cedo
3.Usar ng2ferramenta de debug
4.Deve-se明确了各组件之间的关系,因为不同的组件关系会导致服务的实例的不同
5.O serviço deve ser de nível módulo, não de nível aplicativo.
Agradecemos a leitura, esperamos que ajude a todos, obrigado pelo apoio ao site!