English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Angular2 Detaillierte Erklärung des Mehrstufigen Injectors und Beispiele

angular2 Abhängigkeitsinjektion enthält zu viel Inhalt, einer der Punkte ist der Injector, und dieser ist sehr schwer zu verstehen. Heute werden wir nicht tief in den Inhalt des Injectors einsteigen, sondern können die offiziellen Dokumente konsultieren. Heute sprechen wir über die Ebene des Injectors.

entscheidet, welche konkrete Komponente der Dienstkontainer auswählt.

Zunächst eine kurze Einführung in den Hintergrund: Es gibt3dieser Komponenten AppComponent - Hauptkomponente, DetailList-Komponente (Protokollliste-Komponente), Detail-Komponente (Protokoll-Komponente).

Diese drei Komponenten bilden einen Komponentenbaum, und wir können auch annehmen, dass jede Komponente einen eigenen Injector hat (obwohl dies nicht immer der Fall ist, aber man kann so denken).

Fügen Sie eine Logging-Dienst LoggerService hinzu. Wenn man nach der üblichen Einführungsmethode vorgeht, wird LoggerService im Root-Modul providers bereitgestellt. Dann hat LoggerService im gesamten Anwendungsbereich nur eine Instanz. Was bedeutet das? Es bedeutet, dass man immer die zum ersten Mal erstellte LoggerService in jedem Komponenten erhält, und alle Komponenten teilen sich eine Service-Instanz. Dies kann manchmal eine nützliche Eigenschaft sein, z.B. für globale Konfigurationen.

Global ist nicht unser Hauptfokus in dieser Sitzung, da dies zu gewöhnlich ist. Wir möchten erklären, wie wir in jedem Komponenten eine separate LoggerService-Instanz erhalten, d.h. jede Komponenteninstanz ist unterschiedlich. Dies erfordert ein Verständnis für ng2eine Vorstellung davon haben, was Abhängigkeitsinjektion ist.

Wir erläutern schrittweise, wie dies erreicht wird?

Um die Kollegen, die dieses kurze Dokument lesen, zu unterstützen, habe ich einige grundlegende Codes hinzugefügt.

1.app.module.ts - Anwendungsserver-Modul. Beachten Sie, dass wir hier den loggerService nicht in den Providers registriert haben. Natürlich können wir das auch durch die nachfolgenden Methoden erreichen.

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],//deklarieren Sie die spezifischen Komponenteninformationen, die das aktuelle Modul benötigt
 exports: [],
 providers: [Title],
 bootstrap: [AppComponent]
})
export class AppModule {
 constructor( @Optional() @SkipSelf() parentModule: AppModule) {
 console.log(parentModule);
 if (parentModule) {
  throw new Error(
  'AppModule ist bereits geladen. Importieren Sie es nur im AppModule');
 }
 }
}

2.app.component.ts - Anwendungskernkomponente

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();
 }
}

Bitte beachten Sie, dass wir LoggerService in den Providers der Hauptkomponente registriert haben.

3.app.detailList.ts - Der LoggerService wurde in den Providers der Logger-Liste ebenfalls registriert

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 - Das Log-Component hat keine LoggerService in den Providers registriert.

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();
 }
}

 Jetzt schauen wir uns die Hierarchie von LoggerService in Chrome an.

 

Durch die Überprüfung der Abhängigkeitsbeziehung können wir sehen, dass die Komponente AppComponent die separate LoggerService verwendet, die Komponente DetailList verwendet ebenfalls die separate LoggerService-Instanz, und die Komponente Detail verwendet die LoggerService-Instanz des übergeordneten Komponenten DetailList.

Bislang erreichen wir nicht unseren Anforderungen, unsere Anforderungen sind, dass jeder Komponente eine separate LoggerService-Instanz zugeordnet wird, dann gehen wir davon aus, dass die Providers des Detail-Komponenten möglicherweise vergessen wurden, einzugeben, es ist schwer, den Grund zu testen. Dann fügen wir einen @Host() hinzu, um die Suchbereich des Injectors zu beschränken.

Für die Suchweise des Injectors nach oben, siehe die offizielle Dokumentation.

Um die Debugging-Einfachheit zu erhöhen, fügen wir @Host(). hinzu.

@Host Dekorator beschränkt die Suchaktion auf den Wirtskomponenten

detail.ts - Warnung: Der Detail-Komponente wird der Dekorator @Host() hinzugefügt

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();
 }
}

Es wird angezeigt, dass die Instanz von LoggerService nicht gefunden wurde, die Funktion von @Host() ist es, den Injector daran zu hindern, weiter nach oben zu suchen, sobald er die aktuelle Komponente gefunden hat. Daher erscheint der Fehler, dass die Providers nicht gefunden wurden.

Das Ergebnis mit providers ist das, was wir wollten.

 

Das Problem der Verwendung von mehreren Komponenten mit separaten Dienstinstanzen wurde perfekt gelöst.

 Zusammenfassung:

1.Wenn Sie eine Komponente mit einem Dienst alleine verwenden möchten, müssen Sie den Dienst zuerst im providers einzeln registrieren. Das ist leicht zu verstehen

2.Um mögliche Probleme besser zu erkennen, können Sie den @Host() Dekorator auf den Komponentendienst hinzufügen, um Fehlermeldungen so früh wie möglich auszugeben

3.ng verwenden2Debugging-Tools

4.Klarzustellen sind die Beziehungen zwischen den Komponenten, da verschiedene Beziehungen zu verschiedenen Instanzen von Services führen können

5.Der Service sollte modular sein, nicht applikationsbasiert.

Vielen Dank für das Lesen, ich hoffe, es kann Ihnen helfen, danke für die Unterstützung unseres Standorts!

Vermutlich auch Ihnen gefällt