Wenn wir in der täglichen Arbeit eine Komponente definieren, müssen wir deren Kapselung berücksichtigen. Das heißt, erwarten Sie, dass der in dieser Komponente definierte Stil nur auf diese Komponente wirkt, oder soll er global wirken? In Angular können die Stile einer Komponente im Hostelement der Komponente gekapselt werden, sodass sie den Rest der Anwendung nicht beeinträchtigen. Der Komponentendekorator bietet Kapselungsoptionen, mit denen gesteuert werden kann, wie die Ansichtskapselung auf Komponentenbasis angewendet wird. [Verwandte Tutorial-Empfehlungen: „Angular-Tutorial“]
Es gibt drei Kapselungsmodi in Angular, nämlich ViewEncapsulation.ShadowDom, ViewEncapsulation.Emulated und ViewEncapsulation.None.
Enum ViewEncapsulation exportieren { /** * Emuliert ein natives Shadow-DOM-Kapselungsverhalten durch Hinzufügen eines bestimmten Attributs zum * Hostelement der Komponente und Anwenden des gleichen Attributs auf alle bereitgestellten CSS-Selektoren * über {@link Component#styles Styles} oder {@link Component#styleUrls styleUrls}. * * Dies ist die Standardoption. */ Emuliert = 0, /** * Bietet keinerlei CSS-Stilkapselung, d. h. alle bereitgestellten Stile * über {@link Component#styles Styles} oder {@link Component#styleUrls styleUrls} sind anwendbar * zu jedem HTML-Element der Anwendung, unabhängig von ihrer Host-Komponente. */ Keine = 2, /** * Verwendet die native Shadow-DOM-API des Browsers, um CSS-Stile zu kapseln, was bedeutet, dass sie erstellt werden * ein ShadowRoot für das Hostelement der Komponente, das dann zur Kapselung verwendet wird * das gesamte Styling der Komponente. */ ShadowDom=3 }
Wenn nicht angegeben, wird der Wert von CompilerOptions abgerufen. Die Standard-Compileroption ist ViewEncapsulation.Emulated.
Wenn die Richtlinie auf ViewEncapsulation.Emulated festgelegt ist und die Komponente keine Stile oder styleUrls angibt, wechselt sie automatisch zu ViewEncapsulation.None.
Haben Sie herausgefunden, warum es im Aufzählungstyp keine 1 gibt ? Mehr dazu später.
Lassen Sie die Kapselung von ShadowDom in Angular beiseite und werfen wir zunächst einen Blick darauf, was ShadowDOM ist.
Shadowermöglicht das Anhängen eines versteckten DOM-Baums an den regulären DOM-Baum – er beginnt mit dem Schatten-Wurzelknoten. Unterhalb dieses Wurzelknotens kann es sich um ein beliebiges Element handeln, genau wie ein gewöhnliches DOM-Element.
Hier gibt es einige Shadow-DOM-spezifische Begriffe, die wir verstehen müssen:
Sie können das Shadow-DOM auf die gleiche Weise wie ein normales DOM manipulieren – beispielsweise durch das Hinzufügen untergeordneter Knoten, das Festlegen von Eigenschaften und das Hinzufügen Ihres eigenen Stils zum Knoten (z. B. über die Eigenschaft element.style) oder das Hinzufügen von Stilen zum gesamten Knoten Shadow DOM (z. B. Hinzufügen von Stilen innerhalb von Elementen). Der Unterschied besteht darin, dass Elemente innerhalb des Shadow DOM niemals Elemente außerhalb davon beeinflussen (außer :focus-within), was die Kapselung erleichtert.
Schauen wir uns ein einfaches Beispiel an.
<!DOCTYPE html> <html> <Kopf> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Shadow DOM</title> <Stil> Spanne{ Farbe: grün; } </style> </head> <Körper> <span>Ich bin Root</span> <div id="app"></div> <Skript> let app = document.querySelector('#app'); letshadow1 = app.attachShadow({ mode: 'open'}); let style1 = document.createElement('style'); style1.appendChild(document.createTextNode("span{color: red;}")); shadow1.appendChild(style1); let span1 = document.createElement('span'); span1.textContent = 'Ich bin span.'; shadow1.appendChild(span1); </script> </body> </html>
Das obige Beispiel definiert den globalen Span-Stil und den Span-Stil in ShadowDOM. Es ist ersichtlich, dass sie sich nicht gegenseitig beeinflussen.
Nachdem wir verstanden haben, was ShadowDOM ist, werfen wir einen Blick auf die Kapselung von ShadowDOM in Angular.
Angular verwendet die integrierte Shadow-DOM-API des Browsers, um die Ansicht einer Komponente in einen ShadowRoot (der als Hostelement der Komponente dient) zu verpacken und die bereitgestellten Stile isoliert anzuwenden. ViewEncapsulation.ShadowDom funktioniert nur in Browsern mit integrierter Unterstützung für Shadow DOM. Nicht alle Browser unterstützen dies, weshalb ViewEncapsulation.Emulated der empfohlene und standardmäßige Modus ist.
Verwenden Sie im folgenden Beispiel beispielsweise ViewEncapsulation.ShadowDom .
@Komponente({ Selektor: 'Benutzer-Kind', templateUrl: 'UserChild.component.html', Stile: [` h3{ Farbe: rot; } `], Kapselung: ViewEncapsulation.ShadowDom }) Die Exportklasse UserChildComponent implementiert OnInit { ... }
Auf der laufenden Seite können wir sehen, dass die Benutzer-Kind-Komponente intern in einem ShadowDOM gekapselt ist und der Stil ebenfalls darin gekapselt ist, was keine Auswirkungen auf den externen Stil hat.
Angular ändert die CSS-Selektoren einer Komponente, sodass sie nur für die Ansicht der Komponente gelten und keine Auswirkungen auf andere Elemente in der Anwendung haben (Emulierung des Shadow-DOM-Verhaltens).
Bei Verwendung der Mock-View-Kapselung verarbeitet Angular alle Komponentenstile vor, sodass sie nur für die Ansicht der Komponente gelten. Im DOM der laufenden Angular-Anwendung sind dem Element, das die Komponente enthält, die das Mock-View-Kapselungsmuster verwendet, einige zusätzliche Attribute angehängt:
<hero-details _nghost-pmm-5> <h3 _ngcontent-pmm-5>Mister Fantastic</h3> <hero-team _ngcontent-pmm-5 _nghost-pmm-6> <h4 _ngcontent-pmm-6>Team</h4> </hero-team> </hero-details>
Es gibt zwei solcher Attribute:
Das Attribut | details_nghost |
---|---|
wird | dem Element hinzugefügt, das die Komponentenansicht umschließt , die die ShadowRoots im nativen Shadow-DOM-Wrapper sein wird. Dies ist normalerweise beim Hostelement der Komponente der Fall . |
_ngcontent | wird zu untergeordneten Elementen in Komponentenansichten hinzugefügt und diese Attribute werden verwendet, um Elemente ihren jeweiligen simulierten ShadowRoots (Hostelementen mit passenden _nghost-Attributen) zuzuordnen. |
Die genauen Werte dieser Eigenschaften sind ein privates Implementierungsdetail von Angular. Sie werden automatisch generiert und sollten in Ihrem Anwendungscode nicht referenziert werden.
Sie zielen auf generierte Komponentenstile ab, die in Teile des DOM eingefügt werden:
[_nghost-pmm-5] { Anzeige: Block; Rand: 1 Pixel einfarbig schwarz; } h4[_ngcontent-pmm-6] { Hintergrundfarbe: weiß; Rand: 1px durchgezogen #777; }
Diese Stile werden nachbearbeitet, sodass jeder CSS-Selektor mit dem entsprechenden _nghost- oder _ngcontent-Attribut erweitert wird. Diese modifizierten Selektoren stellen sicher, dass Stile isoliert und gezielt auf die Ansichten einer Komponente angewendet werden.
<p>Kind arbeitet!</p>
p{ Farbe: grün; }
@Component({ Selektor: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.scss'], Kapselung: ViewEncapsulation.Emulated }) Die Exportklasse ChildComponent implementiert OnInit { ... }
Das Ergebnis der Einstellung „ViewEncapsulation.Emulated“ ist, dass kein Shadow-DOM vorhanden ist, sondern die Komponente durch den von Angular bereitgestellten Stilverpackungsmechanismus gekapselt wird, sodass der Stil der Komponente nicht durch äußere Einflüsse beeinflusst wird. Obwohl der Stil weiterhin auf das gesamte Dokument angewendet wird, erstellt Angular einen [_ngcontent-oow-c11]-Selektor für p. Es ist ersichtlich, dass der von uns für die Komponente definierte Stil von Angular geändert wurde. Einfach ausgedrückt: Obwohl es sich um einen globalen Stil handelt, hat er aufgrund der automatischen Auswahl keinen Einfluss auf die Stile anderer Komponenten. Wenn Sie dieses Attribut manuell zu anderen Elementen hinzufügen, wird der Stil auch auf dieses Element angewendet.
Angular wendet keinerlei Form der Ansichtskapselung an, was bedeutet, dass alle für die Komponente angegebenen Stile tatsächlich global angewendet werden und sich auf jedes in der Anwendung vorhandene HTML-Element auswirken können. Dieses Muster ist im Wesentlichen dasselbe wie das Einfügen von Stilen in den HTML-Code selbst.
parent:
<p #caption>parent funktioniert!{{count}}</p> <p #caption>Erstes: {{count}}</p> <span class="red-font">übergeordnetes Element</span> <app-child></app-child>
untergeordnetes Element:
<div style="border: 1px solid green;"> <p>Kind funktioniert!</p> <span class="red-font">Kind</span> </div>
p{ Farbe: grün; } .red-font { Farbe: rot; }
@Component({ Selektor: 'app-child', templateUrl: './child.component.html', styleUrls: ['./child.component.scss'], Kapselung: ViewEncapsulation.None }) Die Exportklasse ChildComponent implementiert OnInit { ... }
Verwendung von ViewEncapsulation.Native in Angular2.
@Komponente({ ..., Kapselung: ViewEncapsulation.Native }) Exportklasse UserComponent {
Die Einstellung „ViewEncapsulation.Native“ führt zur Verwendung der nativen Shadow-DOM-Funktion. Angular rendert die Komponente entsprechend dem vom Browser unterstützten Shadow DOM-Format. Tatsächlich ist dies das spätere ViewEncapsulation.ShadowDom.
haben wir drei Methoden der Angular View-Kapselung und ihre jeweiligen Eigenschaften vorgestellt. Bei der täglichen Arbeit sollten Sie die Kapselungsmethode entsprechend bestimmten Szenarien auswählen.