Heim  >  Artikel  >  Web-Frontend  >  Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

青灯夜游
青灯夜游nach vorne
2022-06-24 15:28:432607Durchsuche

Dieser Artikel vermittelt Ihnen ein detailliertes Verständnis des Abhängigkeitsinjektionsmodus in Angular und teilt Anwendungs- und Gameplay-Fälle des Abhängigkeitsinjektionsmodus. Ich hoffe, dass er für alle hilfreich ist!

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

1 Injektion, ein Kommunikationsmodus und Entwurfsmuster auf Komponentenbaumebene

1.1 Komponentenkommunikationsmodus

In der Angular Engineering-Entwicklung verwenden wir normalerweise die Bindung von Eingabeeigenschaften und die Bindung von Ausgabeereignissen. Komponentenkommunikation jedoch Eingabe und Ausgabe können nur Informationen zwischen übergeordneten und untergeordneten Komponenten weitergeben. Komponenten bilden einen Komponentenbaum basierend auf der aufrufenden Beziehung. Wenn es nur Eigenschaftsbindungen und Ereignisbindungen gibt, müssen zwei nicht direkte Beziehungskomponenten über jeden Verbindungspunkt selbst kommunizieren. Der Mittelsmann muss einige Dinge kontinuierlich verarbeiten und weitergeben Informationen müssen nicht bekannt sein (Abbildung 1 links). Der in Angular bereitgestellte Injectable Service kann in Modulen, Komponenten oder Anweisungen bereitgestellt werden und in Kombination mit der Injektion im Konstruktor dieses Problem lösen (rechts in Abbildung 1). [Verwandte Tutorial-Empfehlung: „Angular-Tutorial“]

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

Abbildung 1 Komponentenkommunikationsmodus

Das linke Bild überträgt Informationen nur über Eltern-Kind-Komponenten. Knoten a und Knoten b müssen zur Kommunikation viele Knoten durchlaufen. Wenn Knoten C Knoten B durch eine Konfiguration steuern möchte, müssen die Knoten zwischen ihnen auch zusätzliche Attribute oder Ereignisse festlegen, um die entsprechenden Informationen transparent zu übertragen. Im Abhängigkeitsinjektionsmodus auf der rechten Seite kann Knoten c einen Dienst für die Kommunikation der Knoten a und b bereitstellen. Knoten a kommuniziert direkt mit dem von Knoten c bereitgestellten Dienst, und Knoten b kommuniziert schließlich auch direkt mit dem von Knoten c bereitgestellten Dienst , die Kommunikation wird vereinfacht und der mittlere Knoten ist nicht an diesen Teil des Inhalts gekoppelt und hat kein offensichtliches Bewusstsein für die Kommunikation, die zwischen der oberen und der unteren Komponente stattfindet.

1.2 Verwenden Sie die Abhängigkeitsinjektion, um eine Umkehrung der Kontrolle zu erreichen. Die Abhängigkeitsinjektion (DI) ist nicht nur für Angular verfügbar. Sie ist ein Mittel zur Implementierung des Entwurfsmusters für die Umkehrung der Kontrolle (IOC). -Kopplung der manuellen Instanziierung Das Problem besteht darin, dass nicht alle Ressourcen von den beiden Parteien verwaltet werden, die die Ressourcen nutzen, sondern vom Ressourcenzentrum oder einem Dritten bereitgestellt werden. Erstens macht die zentrale Ressourcenverwaltung die Ressourcen konfigurierbar und einfach zu verwalten. Zweitens verringert es den Grad der Abhängigkeit zwischen den beiden Parteien, die Ressourcen nutzen, was wir als Kopplung bezeichnen.

Eine Analogie zur realen Welt ist, dass wir beim Kauf eines Produkts wie eines Bleistifts nur ein Geschäft finden müssen, um ein Produkt des gleichen Typs wie einen Bleistift zu kaufen. Es ist uns egal, wo der Bleistift hergestellt wird oder wie das Holz und die Bleistiftmine verklebt werden. Ja, wir benötigen es nur, um die Schreibfunktion eines Bleistifts zu erfüllen. Wir werden keinen Kontakt mit dem jeweiligen Bleistifthersteller oder der Fabrik haben. Das Geschäft kann Bleistifte über die entsprechenden Kanäle kaufen und die Konfigurierbarkeit von Ressourcen realisieren.

In Kombination mit Codierungsszenarien müssen Benutzer insbesondere keine expliziten Instanzen (neue Vorgänge) erstellen, um Instanzen einzufügen und zu verwenden. Die Erstellung von Instanzen wird von den Anbietern bestimmt. Da es sich nicht um den Anbieter oder die Erstellung von Instanzen handelt, kann der Benutzer einige lokale Injektionsmethoden (sekundäre Konfiguration von Token) verwenden, um schließlich den Instanzersetzungs- und Abhängigkeitsinjektionsmodus (AOP) zu erreichen ) ergänzen sich.

2 Abhängigkeitsinjektion in Angular

Abhängigkeitsinjektion ist eines der wichtigsten Kernmodule des Angular-Frameworks und bietet nicht nur die Injektion von Diensttypen, sondern der Komponentenbaum selbst ist ein Injektionsabhängigkeitsbaum kann auch injiziert werden. Das heißt, im Angular-Framework können untergeordnete Komponenten übergeordnete Komponenteninstanzen über das Token der übergeordneten Komponente (normalerweise den Klassennamen) injizieren. Bei der Entwicklung von Komponentenbibliotheken gibt es viele Fälle, in denen Interaktion und Kommunikation durch das Einfügen übergeordneter Komponenten erreicht werden, einschließlich Parametermontage, Zustandsfreigabe und sogar des Abrufens des DOM des Knotens, auf dem sich die übergeordnete Komponente befindet usw.

2.1 Abhängigkeitsauflösung

Um Angular-Injection verwenden zu können, müssen Sie zunächst den Injektionsauflösungsprozess verstehen. Ähnlich wie beim Parsing-Prozess von node_modules werden, wenn keine Abhängigkeiten gefunden werden, die Abhängigkeiten immer zur übergeordneten Ebene weitergeleitet, um Abhängigkeiten zu finden. Die alte Version von Angular (vor v6

) unterteilt den Injektionsanalyseprozess in mehrstufige Modulinjektoren, mehrstufige Komponenteninjektoren und Elementinjektoren. Die neue Version (nach

v9) wird zu einem zweistufigen Modell vereinfacht. Die erste Abfragekette ist der statische Elementinjektor, Komponenteninjektor usw. auf DOM-Ebene, zusammenfassend als Elementinjektor bezeichnet, und die andere Abfragekette ist der Modulinjektor . Die Reihenfolge der Analyse und der Standardwert nach einem Analysefehler werden im offiziellen Codekommentardokument (provider_flag) genauer erläutert.

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

Abbildung 2 Der Abhängigkeitssuchprozess des zweistufigen Injektors (Bildquelle)

Das heißt, Komponenten/Anweisungen und die Bereitstellung injizierter Inhalte auf der Komponenten-/Anweisungsebene suchen zunächst nach Abhängigkeiten in den Elementen in der Komponentenansicht bis zum Stammelement. Wenn es nicht gefunden wird, durchsuchen Sie das übergeordnete Modul des Moduls, bis das Stammmodul und das Plattformmodul in dem Modul, in dem sich das Element befindet, referenziert werden (einschließlich Modulreferenzen und Routing-Lazy-Loading-Referenzen). befindet sich derzeit.

Beachten Sie, dass der Injektor hier eine Vererbung hat. Der Elementinjektor kann die Suchfunktion des Injektors des übergeordneten Elements erstellen und erben, und der Modulinjektor ist ähnlich. Nach der kontinuierlichen Vererbung ähnelt es ein wenig der Prototypkette von js-Objekten.

2.2 Konfigurationsanbieter

Wenn wir die Reihenfolgepriorität der Abhängigkeitsauflösung verstehen, können wir Inhalte auf der entsprechenden Ebene bereitstellen. Wir wissen bereits, dass es zwei Arten gibt: Modulinjektion und Elementinjektion.

  • Modulinjektor: Anbieter können im Metadatenattribut von @NgModule konfiguriert werden, und Sie können auch die nach Version 6 bereitgestellte @Injectable-Anweisung verwenden. Die ProvideIn-Anweisung ist der Modulname, „root“ usw. (Eigentlich gibt es zwei Injektoren über dem Root-Modul, Platform und Null. Sie werden hier nicht besprochen.)

  • Elementinjektor: Provider, ViewProviders oder Provider.

in den @Directive-Metadaten der Direktive Darüber hinaus kann der @Injectable-Dekorator nicht nur zum Deklarieren eines Modulinjektors verwendet werden, sondern auch als Elementinjektor deklariert werden. Häufiger wird es als im Stammverzeichnis bereitgestellt deklariert, um einen Singleton zu implementieren. Es integriert Metadaten über die Klasse selbst, um zu vermeiden, dass Module oder Komponenten den Anbieter direkt explizit deklarieren. Wenn die Klasse also keinen Komponentendirektivendienst und andere Klassen zum Einfügen hat, ist kein Code mit der Typdeklaration verknüpft Es kann vom Compiler ignoriert werden, wodurch Shake the Tree erreicht wird.

Eine andere Möglichkeit, dies bereitzustellen, besteht darin, den Wert direkt bei der Deklaration von InjectionToken anzugeben.

Hier sind die Kurzvorlagen für diese Methoden:

@NgModule({  providers: [
    // 模块注入器
  ]
})
export class MyModule {}
@Component({  providers: [
    // 元素注入器 - 组件
  ],  
  viewProviders: [
      // 元素注入器- 组件视图
  ]
})
export class MyComponent {}
@Directive({  providers: [
   // 元素注入器 - 指令
 ]
})
export class MyDirective {}
@Injectable({
 providedIn: 'root'
})
export class MyService {}
export const MY_INJECT_TOKEN = new InjectionToken<myclass>('my-inject-token', {
 providedIn: 'root',
 factory: () => {
    return new MyClass();
 }
});</myclass>

Verschiedene Optionen für die Bereitstellung von Abhängigkeitsspeicherorten bringen einige Unterschiede mit sich, die sich letztendlich auf die Größe des Pakets, den Umfang der Abhängigkeiten, die eingefügt werden können, und den Lebenszyklus von Abhängigkeiten auswirken. Es gibt verschiedene anwendbare Lösungen für verschiedene Szenarien, z. B. Singleton (Root), Dienstisolation (Modul), mehrere Bearbeitungsfenster (Komponente) usw. Sie sollten einen angemessenen Speicherort wählen, um unangemessene gemeinsame Informationen oder redundante Codeverpackung zu vermeiden.

2.3 Verschiedene Wertfunktionstools

Wenn Sie nur Instanzinjektion bereitstellen, wird die Flexibilität der Angular-Framework-Abhängigkeitsinjektion nicht angezeigt. Angular bietet viele flexible Injektionstools, useValue verwendet statische Werte, useExisting kann vorhandene Instanzen wiederverwenden und useFactory wird über Funktionen mit angegebenen Deps und angegebenen Konstruktorparametern erstellt. Sie können das Token einer Klasse abschneiden und durch eine andere von Ihnen vorbereitete Instanz ersetzen. Sie können zuerst ein Token erstellen, um den Wert oder die Instanz zu speichern, und es dann erneut ersetzen, wenn Sie es später verwenden müssen Die Factory-Funktion gibt sie zurück. Die lokalen Informationen der Instanz werden einem anderen Objekt oder Attributwert zugeordnet. Das Gameplay hier wird anhand der folgenden Fälle erklärt, daher werde ich hier nicht näher darauf eingehen. Auf der offiziellen Website finden Sie auch viele Referenzbeispiele.

2.4 Injektionsverbrauch und Dekorator

Injection in Angular kann im Konstruktor injiziert werden, oder Sie können den Injektor erhalten, um die vorhandenen injizierten Elemente über die get-Methode abzurufen.

Angular unterstützt das Hinzufügen von Dekoratoren, die beim Injizieren markiert werden sollen,

  • @Host(), um die Blasenbildung zu begrenzen,
  • @Self() auf das Element selbst,
  • @SkipSelf(), um es auf das Element selbst zu beschränken,
  • @Optional () Als optional markiert
  • @Inject() beschränkt auf benutzerdefinierte Token-Token

Hier ist ein Artikel „@Self oder @Optional @Host? Der visuelle Leitfaden für Angular DI-Dekoratoren.“, der sehr anschaulich die Unterschiede in den Instanzen zeigt wird getroffen, wenn zwischen übergeordneten und untergeordneten Komponenten unterschiedliche Dekoratoren verwendet werden. Abbildung 3: Filterergebnisse verschiedener injizierter Dekoratoren Anweisungen. Die offizielle Erklärung des @Host-Dekorators lautet:

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)...eine Abhängigkeit von jedem Injektor abrufen, bis das Host-Element erreicht ist

Host bedeutet hier Host. Der @Host-Dekorator beschränkt den Umfang der Abfrage auf das Host-Element. Was ist ein Hostelement? Wenn Komponente B eine Komponente ist, die von der Vorlage von Komponente A verwendet wird, ist die Instanz von Komponente A das Hostelement der Instanz von Komponente B. Der von der Komponentenvorlage generierte Inhalt wird als Ansicht bezeichnet. Die gleiche Ansicht kann für verschiedene Komponenten unterschiedliche Ansichten sein. Wenn Komponente A Komponente B innerhalb ihres eigenen Vorlagenbereichs verwendet (siehe Abbildung 4), ist die durch den Vorlageninhalt von A gebildete Ansicht (roter Kastenteil) die eingebettete Ansicht von Komponente A, und Komponente B befindet sich innerhalb dieser Ansicht, also für B , diese Ansicht ist die Hostansicht von B. Der Dekorator @Host beschränkt den Suchbereich auf die Hostansicht. Wenn er nicht gefunden wird, wird er nicht angezeigt.

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

Abbildung 4 Inline-Ansicht und Host-Ansicht

3 Fälle und Gameplay

Nehmen wir einen realen Fall, um zu sehen, wie die Abhängigkeitsinjektion funktioniert, wie Fehler behoben werden und was sonst noch getan werden kann. Spielen.

3.1 Fall 1: Das modale Fenster erstellt eine dynamische Komponente, aber die Komponente kann nicht gefunden werden

Die modale Fensterkomponente der DevUI-Komponentenbibliothek stellt einen Dienst ModalService bereit, der ein modales Feld öffnen und so konfiguriert werden kann automatisch definierte Komponenten. BWL-Studenten melden bei der Verwendung dieser Komponente häufig Fehler und sagen, dass das Paket die benutzerdefinierte Komponente nicht finden kann.

Zum Beispiel der folgende Fehlerbericht:

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

Abbildung 5 Bei Verwendung von ModalService kann der Fehlerbericht beim Erstellen einer Komponente, die auf EditorX verweist, den entsprechenden Dienstanbieter nicht finden.

Analysieren Sie, wie ModalService benutzerdefinierte Komponenten erstellt, ModalService-Quellcode Öffnen Sie die Funktion Zeile 52 und Zeile 95. Wie Sie sehen können, wird der von ModalService injizierte componentFactoryResolver verwendet, wenn componentFactoryResolver nicht übergeben wird. In den meisten Fällen führt das Unternehmen DevUIModule einmal im Stammmodul ein, ModalModule jedoch nicht im aktuellen Modul. Das heißt, die aktuelle Situation in Abbildung 6 sieht so aus. Gemäß Abbildung 6 gibt es im Injektor von ModalService keinen EditorXModuleService. componentFactoryResolver如果没有传入就使用ModalService注入的componentFactoryResolver。而大多数情况下,业务会在根模块引入一次DevUIModule,但是不会在当前模块里引入ModalModule。也就是现状图6是这样的。根据图6,ModalService的injector内是没有EditorXModuleService的。

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

图6 模块服务提供关系图

根据注入器的继承,解决办法有四个:

  • 把 EditorXModule 放到 ModalModule 声明的地方,这样注入器就能找到EditorXModule提供的EditorModuleService —— 这是最糟糕的一种解法,本身loadChildren实现的懒加载就是为了减少首页模块的加载,结果是子页内需要用到的内容却放在AppModule,首次加载就把富文本的大模块给加载了,加重了FMP(First Meaningful Paint),不可采取。

  • 在引入 EditorXModule 且使用 ModalService 的模块里引入 ModalService —— 可取。仅有一种情况不太可取,就是调用 ModalService 的是另一个靠顶层的公共 Service,这样还是把不必要的模块放在了上层去加载。

  • 在触发使用ModalService的组件,注入当前模块的componentFactoryResolver,并传给ModalService的open函数参数 —— 可取, 可以在真正使用的地方再引入EditorXModule。

  • 在使用的模块里,手动提供一个ModalService —— 可取,解决了注入搜索的问题。

四种方法其实都是在解决 ModalService 所用的componentFactoryResolver

Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

Bild 6 Beziehungsdiagramm zur Bereitstellung von Moduldiensten

Entsprechend der Vererbung des Injektors gibt es vier Lösungen:

  • Legen Sie das EditorXModule dort ab, wo das ModalModule deklariert ist. So kann der Injektor den von EditorXModule bereitgestellten EditorModuleService finden. Das von LoadChildren selbst implementierte verzögerte Laden besteht darin, das Laden des Homepage-Moduls zu reduzieren Beim ersten Laden wird das große Rich-Text-Modul geladen, wodurch der FMP (First Meaningful Paint) erhöht wird und nicht übernommen werden kann.

Führen Sie ModalService in dem Modul ein, das EditorXModule einführt und ModalService verwendet – ratsam. Es gibt nur eine Situation, die nicht ratsam ist: Der Aufruf von ModalService ist ein weiterer öffentlicher Dienst der obersten Ebene, der immer noch unnötige Module zum Laden auf die obere Ebene legt.

  • Wenn Sie die Komponente auslösen, die ModalService verwendet, fügen Sie den componentFactoryResolver des aktuellen Moduls ein und übergeben Sie ihn an den offenen Funktionsparameter von ModalService. Es ist ratsam, dort EditorXModule einzuführen wird tatsächlich verwendet.

  • Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)Im verwendeten Modul empfiehlt es sich, manuell einen ModalService bereitzustellen, der das Problem der injizierenden Suche löst.
  • Die vier Methoden lösen tatsächlich das Problem von EditorXModuleService in der internen Kette des Injektors von componentFactoryResolver, der von ModalService verwendet wird. Indem sichergestellt wird, dass die Suchkette auf zwei Ebenen erfolgt, kann dieses Problem gelöst werden. Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Zusammenfassung der Wissenspunkte

    : Modulinjektorvererbung und Suchbereich. 🎜🎜🎜3.2 Fall 2: CdkVirtualScrollFor kann CdkVirtualScrollViewport nicht finden🎜🎜🎜Wenn wir dieselbe Vorlage an mehreren Stellen verwenden, extrahieren wir normalerweise die gemeinsamen Teile über die Vorlage. Bei der vorherigen Entwicklung der DevUI Select-Komponente wollte der Entwickler die gemeinsamen Teile extrahieren . Es wurde ein Fehler gemeldet. 🎜🎜🎜🎜🎜🎜🎜🎜Abbildung 7 Codebewegung und Injektionsfehler nicht gefunden🎜

    Dies liegt daran, dass die CdkVirtualScrollFor-Anweisung einen CdkVirtualScrollViewport injizieren muss. Das Vererbungssystem für Elementinjektionen erbt jedoch das DOM der statischen AST-Beziehung und die dynamische Funktion funktioniert nicht. Daher tritt das folgende Abfrageverhalten auf .

    Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 8 Suchbereich der Elementinjektor-Abfragekette

    Endgültige Lösung: Entweder 1) Behalten Sie die ursprüngliche Codeposition bei, oder 2) Sie müssen die gesamte Vorlage einbetten, um sie zu finden.

    Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 9 Das eingebettete Gesamtmodul ermöglicht es CdkVitualScrollFo, CdkVirtualScrollViewport zu finden (Lösung 2)

    Zusammenfassung der Wissenspunkte: Die Abfragekette des Elementinjektors ist der DOM-Elementvorfahre der statischen Vorlage.

    3.3 Fall 3: Die Formularüberprüfungskomponente ist in einer Unterkomponente gekapselt und kann nicht überprüft werden

    Dieser Fall stammt aus diesem Blog „Angular: Verschachteltes vorlagengesteuertes Formular“.

    Das gleiche Problem ist auch bei der Verwendung der Formularvalidierung aufgetreten. Wie in Abbildung 10 dargestellt, kapseln wir aus bestimmten Gründen die Adressen der drei Felder zur Wiederverwendung in einer Komponente.

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 10 Kapseln Sie die drei Adressfelder des Formulars in eine Unterkomponente.

    Zu diesem Zeitpunkt werden wir einen Fehler finden: ngModelGroup benötigt einen ControlContainer darin der Host , der der von der ngForm-Direktive bereitgestellte Inhalt ist. ngModelGroup需要一个host内部的ControlContainer,也就是ngForm指令提供的内容。

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    图11 ngModelGroup 找不到ControlContainer

    查看ngModelGroup代码可以看到它只添加了host装饰器的限制。

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    图12 ng_model_group.ts限定了注入ControlContainer的范围

    这里可以使用viewProvider搭配usingExisting给AddressComponent的宿主视图增加ControlContainer的Provider

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    图13 使用viewProviders给嵌套组件提供外部的Provider

    知识点小结:viewProvider 和 usingExisting 搭配的妙用。

    3.4 案例四:拖拽模块提供的Service,由于懒加载,不是单例了,导致无法互相拖拽

    内部的业务平台有涉及跨多个模块的拖拽,由于涉及了loadChildren懒加载,每个模块会单独打包DevUI组件库的DragDropModule,该Module提供了一个DragDropService。拖拽指令分为可拖起指令Draggable和可放置指令Droppable,两个指令通过DragDropService进行通信。 本来引入同一个模块使用模块提供的Service是可以通信的,但是懒加载后DragDropModule模块被打包了两次,也对应产生两份隔离的实例。这时候处于一个懒加载模块里的Draggable指令就无法与另一个懒加载模块里的Droppable指令进行通信了,因为此时DragDropService并不是同个实例了。

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    图14 懒加载模块导致服务不是同一实例/单例

    这里明显我们的述求是需要单例,而单例的做法通常就是providerIn: 'root'

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Bild 11 ngModelGroup kann ControlContainer nicht finden

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)Wenn Sie sich den ngModelGroup-Code ansehen, können Sie sehen, dass er nur die Einschränkung des Host-Dekorators hinzufügt.

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Bild 12 ng_model_group.ts begrenzt den Umfang der Injektion von ControlContainer1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Hier können Sie viewProvider mit usingExisting verwenden, um den Provider von ControlContainer zur Hostansicht von AddressComponent hinzuzufügen

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    🎜Abbildung 13 Verwenden Sie viewProviders, um externe Anbieter für verschachtelte Komponenten bereitzustellen🎜🎜🎜Zusammenfassung der Wissenspunkte🎜: viewProvider und usingExisting Kollokation Die wunderbare Verwendung. 🎜

    🎜3.4 Fall 4: Der vom Drag-and-Drop-Modul bereitgestellte Dienst ist aufgrund des verzögerten Ladens kein Singleton mehr, was dazu führt, dass es nicht möglich ist, sich gegenseitig per Drag-and-Drop zu verschieben🎜🎜🎜 Die interne Geschäftsplattform umfasst mehrere. Zum Ziehen von Modulen verpackt jedes Modul aufgrund des verzögerten Ladens von LoadChildren separat das DragDropModule der DevUI-Komponentenbibliothek, die einen DragDropService bereitstellt. Drag-and-Drop-Anweisungen sind in Draggable-Anweisungen und Droppable-Anweisungen unterteilt. Die beiden Anweisungen kommunizieren über DragDropService. Ursprünglich war es möglich, durch Einführung desselben Moduls und Nutzung des vom Modul bereitgestellten Dienstes zu kommunizieren. Nach dem verzögerten Laden wurde das DragDropModule-Modul jedoch zweimal gepackt, was ebenfalls zu zwei isolierten Instanzen führte. Zu diesem Zeitpunkt kann die Draggable-Anweisung in einem verzögert geladenen Modul nicht mit der Droppable-Anweisung in einem anderen verzögert geladenen Modul kommunizieren, da es sich bei DragDropService zu diesem Zeitpunkt nicht um dieselbe Instanz handelt. 🎜🎜1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)🎜🎜Bild 14 Das verzögerte Laden von Modulen führt dazu, dass Dienste nicht dieselbe Instanz/einziger Fall sind🎜🎜Es ist offensichtlich, dass unsere Anforderung hier darin besteht, dass wir einen Singleton benötigen, und die Singleton-Methode ist normalerweise providerIn: 'root' , dann ist es nicht besser, den DragDropService der Komponentenbibliothek nicht auf Modulebene, sondern direkt im Root-Sektor bereitzustellen? Aber wenn man genau darüber nachdenkt, gibt es hier noch andere Probleme. Die Komponentenbibliothek selbst wird für die Nutzung durch verschiedene Unternehmen bereitgestellt. Wenn einige Unternehmen zwei entsprechende Drag-and-Drop-Gruppen an zwei Stellen auf der Seite haben, möchten sie nicht verknüpft werden. Zu diesem Zeitpunkt zerstört der Singleton diese natürliche Isolation basierend auf Modulen. 🎜🎜Dann wäre es sinnvoller, den Singleton-Ersatz durch die Geschäftsseite zu implementieren. Denken Sie an die Abhängigkeitsabfragekette, die wir zuvor erwähnt haben. Der Elementinjektor wird zuerst durchsucht. Wenn er nicht gefunden wird, wird der Modulinjektor gestartet. Die Ersatzidee besteht also darin, dass wir Anbieter auf Elementebene bereitstellen können. 🎜🎜🎜🎜🎜Abbildung 15 Verwenden Sie die Erweiterungsmethode, um einen neuen DragDropService abzurufen und ihn als auf der Stammebene bereitgestellt zu markieren🎜🎜🎜🎜🎜🎜🎜

    Abbildung 16 Sie können denselben Selektor verwenden, um wiederholte Anweisungen zu überlagern, der Draggable-Anweisung und der Droppable-Anweisung der Komponentenbibliothek eine zusätzliche Anweisung zu überlagern und den Token von DragDropService durch den DragDropGlobalService zu ersetzen, der einen Singleton im Stammverzeichnis bereitgestellt hat

    As Wie in den Abbildungen 15 und 16 gezeigt, werden wir über den Elementinjektor Anweisungen überlagert, um das DragDropService-Token durch eine Instanz unseres eigenen globalen Singletons zu ersetzen. Zu diesem Zeitpunkt, an dem wir den globalen Singleton DragDropService verwenden müssen, müssen wir nur das Modul einführen, das diese beiden zusätzlichen Anweisungen deklariert und exportiert, damit die Draggable-Anweisung Droppable-Anweisung der Komponentenbibliothek über Lazy-Loading-Module hinweg kommunizieren kann.

    Zusammenfassung der Wissenspunkte: Elementinjektoren haben eine höhere Priorität als Modulinjektoren.

    3.5 Fall 5: So hängen Sie das Dropdown-Menü an das lokale Problem im lokalen Designfunktionsszenario an

    Das Design der DevUI-Komponentenbibliothek verwendet benutzerdefinierte CSS-Attribute (CSS-Variablen), um Folgendes zu deklarieren: den CSS-Variablenwert von root, um den Theme-Wechsel zu erreichen. Wenn wir Vorschauen verschiedener Themen gleichzeitig in einer Schnittstelle anzeigen möchten, können wir CSS-Variablen lokal im DOM-Element neu deklarieren, um die Funktion lokaler Themen zu erreichen. Ich habe diese Methode verwendet, um ein Thema lokal anzuwenden, als ich einen Themen-Dither-Generator erstellt habe.

    1Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 17 Lokale Themenfunktion

    Aber es reicht nicht aus, nur CSS-Variablenwerte lokal anzuwenden. Es gibt einige Dropdown-Popup-Ebenen, die standardmäßig an der Rückseite des Körpers angebracht sind Ihre Bindungsschicht liegt außerhalb der lokalen Variablen. Dies führt zu einem sehr peinlichen Problem. Das Dropdown-Feld der lokalen Theme-Komponente zeigt den Stil des externen Themes an.

    Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 18 Das an die externe Komponente im Teilthema angehängte Overlay-Dropdown-Box-Thema ist falsch

    Was soll ich zu diesem Zeitpunkt tun? Wir sollten den Befestigungspunkt zurück in den lokalen Theme-Dom verschieben.

    Es ist bekannt, dass das Overlay der DatePickerPro-Komponente der DevUI-Komponentenbibliothek das Overlay von Angular CDK verwendet. Nach einer Analyserunde haben wir es wie folgt durch Injektion ersetzt:

    1) Zuerst erben wir OverlayContainer und implementieren unseren Eigener ElementOverlayContainer wie unten gezeigt.

    2Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 19 Passen Sie den ElementOverlayContainer an und ersetzen Sie die _createContainer-Logik

    2) Stellen Sie dann direkt unseren neuen ElementOverlayContainer auf der Komponentenseite der Vorschau bereit und stellen Sie ein neues Overlay bereit, damit das neue Overlay unseren OverlayContainer verwenden kann. Ursprünglich werden Overlay und OverlayContainer beide im Root bereitgestellt. Hier müssen wir diese beiden behandeln.

    2Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 20 Ersetzen Sie den OverlayContainer durch den benutzerdefinierten ElementOverlayContainer und stellen Sie ein neues Overlay bereit.

    Gehen Sie nun zur Vorschau-Website. Das DOM der Popup-Ebene wird erfolgreich an das Komponentenvorschauelement angehängt.

    2Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 21 Der Overlay-Container von cdk ist an den angegebenen Dom angehängt, und die Teilthemenvorschau ist erfolgreich

    Es gibt auch eine benutzerdefinierte OverlayContainerRef in der DevUI-Komponentenbibliothek für einige Komponenten und modale Box-Schubladenbänke, die auch müssen entsprechend angepasst werden ersatz. Schließlich können Popup-Fenster und Popup-Ebenen realisiert werden, um lokale Themen perfekt zu unterstützen.

    Zusammenfassung der Wissenspunkte: Gute Abstraktionsmuster können Module austauschbar machen und eine elegante Aspektprogrammierung erreichen.

    3.6 Fall 6: CdkOverlay erfordert das Hinzufügen der CdkScrollable-Anweisung zur Bildlaufleiste, sie kann jedoch nicht zur äußersten Ebene der Eingabekomponente hinzugefügt werden.

    Wie gehe ich damit um? Ich möchte über einige weniger formale Methoden sprechen. Es ist für jeden praktisch, die Natur des Anbieters zu verstehen. Die Konfiguration des Anbieters dient im Wesentlichen dazu, ihn bei der Instanziierung oder Zuordnung zu einer vorhandenen Instanz zu unterstützen.

    Wir wissen, dass wir bei Verwendung von cdkOverlay die cdkScrollable-Anweisung zur Bildlaufleiste hinzufügen müssen, wenn wir möchten, dass das Popup-Fenster der Bildlaufleiste folgt und an der richtigen Position angezeigt wird.

    Es ist immer noch die gleiche Szene wie im vorherigen Beispiel. Der Einfachheit halber habe ich die Bildlaufleiste auf den Host der Komponente geschrieben.

    2Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 22 Die Bildlaufleiste für den Inhaltsüberlauf schreibt overflow:auto in die Komponente:host

    Auf diese Weise stoßen wir auf ein schwierigeres Problem. Das Modul wird durch die Routerdefinition angegeben, das heißt, es wird nicht angezeigt Rufen Sie <app-theme-picker-customize></app-theme-picker-customize> auf die gleiche Weise auf. Wie füge ich die cdkScrollable-Anweisung hinzu? Die Lösung ist wie folgt. Ein Teil des Codes ist hier versteckt und nur der Kerncode bleibt übrig.

    2Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 23 Erstellen Sie eine Instanz durch Injektion und rufen Sie den Lebenszyklus manuell auf.

    Hier wird eine Instanz von cdkScrollable durch Injektion generiert und der Lebenszyklus wird synchron während der Lebenszyklusphase der Komponente aufgerufen.

    Diese Lösung ist keine formale Methode, aber sie löst das Problem. Sie bleibt hier als Idee und Erkundung für den Leser.

    Zusammenfassung der Wissenspunkte: Der Anbieter der Abhängigkeitsinjektionskonfiguration kann Instanzen erstellen. Bitte beachten Sie jedoch, dass Instanzen als gewöhnliche Serviceklassen behandelt werden und keinen vollständigen Lebenszyklus haben können.

    3.7 Weitere Spielmöglichkeiten: Passen Sie die Ersatzplattform an, um die Interaktion des Angular-Frameworks zu realisieren, das auf dem Terminal ausgeführt wird.

    Sie können sich auf diesen Blog-Beitrag beziehen: „Angular-Anwendungen im Terminal rendern

    2Vertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall)

    Abbildung 24 Ersetzung Der RendererFactory2-Renderer und andere Inhalte ermöglichen die Ausführung von Angular auf dem Terminal. Der Autor hat RendererFactory2 und andere Renderer ersetzt, um die Ausführung von Angular-Anwendungen auf dem Terminal zu ermöglichen. Das ist die Flexibilität des Angular-Designs. Sogar die Plattform ist leistungsstark und flexibel. Detaillierte Details zum Austausch finden Sie im Originalartikel und werden hier nicht näher erläutert.

    Zusammenfassung der Wissenspunkte

    : Die Stärke der Abhängigkeitsinjektion besteht darin, dass der Anbieter sie selbst konfigurieren und schließlich die Ersetzungslogik implementieren kann.

    4 Zusammenfassung

    Dieser Artikel stellt den Abhängigkeitsinjektionsmodus der Kontrollumkehr und seine Vorteile vor. Er stellt vor, wie die Abhängigkeitsinjektion in Angular nach Abhängigkeiten sucht, wie man Anbieter konfiguriert und wie man begrenzte und filternde Dekoratoren verwendet, um das Gewünschte zu erhalten Die Ergebnisse werden weiter verwendet, um zu analysieren, wie die Wissenspunkte der Abhängigkeitsinjektion kombiniert werden können, um die bei der Entwicklung und Programmierung auftretenden Probleme durch N Fälle zu lösen.

    Mit einem korrekten Verständnis des Abhängigkeitssuchprozesses können wir den Anbieter am genauen Standort konfigurieren (Fall 1 und 2), andere Instanzen durch Singletons ersetzen (Fall 4 und 5) und sogar die Einschränkungen verschachtelter Komponentenpakete überwinden Siehe das bereitgestellte Beispiel (Fall 3) oder verwenden Sie die bereitgestellte Methodenkurve, um die Befehlsinstanziierung zu implementieren (Fall 6).

    Der fünfte Fall scheint ein einfacher Ersatz zu sein, aber um eine Codestruktur schreiben zu können, die ersetzt werden kann, ist ein tiefgreifendes Verständnis des Injektionsmodus und eine bessere und vernünftige Abstraktion jeder Funktion erforderlich Wenn dies angemessen ist, ist es nicht möglich, die Abhängigkeitsinjektion auszunutzen. Der Injektionsmodus bietet mehr Platz für steckbare, steckbare und teilebasierte Module, wodurch die Kopplung reduziert und die Flexibilität erhöht wird, sodass Module eleganter und harmonischer zusammenarbeiten können.

    Die leistungsstarke Abhängigkeitsinjektionsfunktion kann nicht nur die Kommunikationspfade von Komponenten optimieren, sondern, was noch wichtiger ist, auch eine Steuerungsumkehr erreichen, wodurch gekapselte Komponenten mehr Aspekten der Programmierung ausgesetzt werden und die Implementierung einiger geschäftsspezifischer Logik auch flexibler werden kann.

    Weitere Kenntnisse zum Thema Programmierung finden Sie unter:

    Programmiervideos

    ! !

    Das obige ist der detaillierte Inhalt vonVertiefendes Verständnis des Abhängigkeitsinjektionsmusters in Angular (Spielfall). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen