Dans le travail quotidien, lorsque nous définissons un Component , nous devons considérer son encapsulation , c'est-à-dire, attendez-vous à ce que le style défini dans ce composant agisse uniquement sur ce composant, ou souhaitez-vous qu'il agisse globalement. Dans Angular, les styles d'un composant peuvent être encapsulés dans l'élément hôte du composant afin qu'ils n'affectent pas le reste de l'application. Le décorateur de composants fournit des options d'encapsulation qui peuvent être utilisées pour contrôler la façon dont l'encapsulation de la vue est appliquée pour chaque composant. [Recommandations du didacticiel associées : "tutoriel angulaire"]
Il existe trois modes d'encapsulation dans Angular, à savoir ViewEncapsulation.ShadowDom, ViewEncapsulation.Emulated et ViewEncapsulation.None.
exporter l'énumération ViewEncapsulation { /** * Émule un comportement d'encapsulation natif Shadow DOM en ajoutant un attribut spécifique au * élément hôte du composant et appliquant le même attribut à tous les sélecteurs CSS fournis * via {@link Component#styles styles} ou {@link Component#styleUrls styleUrls}. * * Il s'agit de l'option par défaut. */ Émulé = 0, /** * Ne fournit aucune sorte d'encapsulation de style CSS, ce qui signifie que tous les styles fournis * via {@link Component#styles styles} ou {@link Component#styleUrls styleUrls} sont applicables * à n'importe quel élément HTML de l'application quel que soit son composant hôte. */ Aucun = 2, /** * Utilise l'API Shadow DOM native du navigateur pour encapsuler les styles CSS, ce qui signifie qu'elle crée * un ShadowRoot pour l'élément hôte du composant qui est ensuite utilisé pour encapsuler * tout le style du composant. */ DomOmbre=3 }
Si elle n’est pas fournie, la valeur est obtenue à partir de CompilerOptions. L'option par défaut du compilateur est ViewEncapsulation.Emulated.
Si la stratégie est définie sur ViewEncapsulation.Emulated et que le composant ne spécifie pas de styles ou de styleUrls, il passera automatiquement à ViewEncapsulation.None.
Avez-vous découvert pourquoi il n'y a pas de 1 dans le type énumération ? Nous en reparlerons plus tard.
Mis à part l'encapsulation de ShadowDom dans Angular, jetons d'abord un coup d'œil à ce qu'est ShadowDOM.
Shadow DOM permet d'attacher une arborescence DOM cachée à l'arborescence DOM normale - elle commence par le nœud racine fantôme. Au-dessous de ce nœud racine, il peut s'agir de n'importe quel élément, tout comme un élément DOM ordinaire.
Ici, il y a quelques termes spécifiques au Shadow DOM que nous devons comprendre :
Vous pouvez manipuler le Shadow DOM de la même manière qu'un DOM classique - par exemple en ajoutant des nœuds enfants, en définissant des propriétés et en ajoutant votre propre style au nœud (par exemple, via la propriété element.style) ou en ajoutant des styles à l'ensemble. Shadow DOM (par exemple, ajout de styles dans les éléments). La différence est que les éléments à l'intérieur du Shadow DOM n'affecteront jamais les éléments à l'extérieur (sauf :focus-within), ce qui facilite l'encapsulation.
Regardons un exemple simple.
<!DOCTYPEhtml> <html> <tête> <méta charset="UTF-8"> <méta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <titre>Shadow DOM</title> <style> portée{ couleur : vert ; } </style> </tête> <corps> <span>Je suis Root</span> <div id="app"></div> <script> let app = document.querySelector('#app'); let shadow1 = app.attachShadow({ mode : 'open'}); let style1 = document.createElement('style'); style1.appendChild(document.createTextNode("span{color: red;}")); shadow1.appendChild(style1); laissez span1 = document.createElement('span'); span1.textContent = 'Je suis span.'; shadow1.appendChild(span1); </script> </corps> </html>
L'exemple ci-dessus définit le style span global et le style span dans shadowDOM. On peut voir qu'ils ne sont pas affectés l'un par l'autre.
Après avoir compris ce qu'est ShadowDOM, jetons un coup d'œil à l'encapsulation de ShadowDOM dans Angular.
Angular utilise l'API Shadow DOM intégrée au navigateur pour envelopper la vue d'un composant dans un ShadowRoot (qui sert d'élément hôte du composant) et appliquer les styles fournis de manière isolée. ViewEncapsulation.ShadowDom ne fonctionne que dans les navigateurs avec prise en charge intégrée du Shadow DOM. Tous les navigateurs ne le prennent pas en charge, c'est pourquoi ViewEncapsulation.Emulated est le mode recommandé et par défaut.
Par exemple, dans l'exemple suivant, utilisez ViewEncapsulation.ShadowDom .
@Composant({ sélecteur : 'utilisateur-enfant', templateUrl : 'UserChild.component.html', styles : [` h3{ couleur : rouge ; } `], encapsulation : ViewEncapsulation.ShadowDom }) classe d'exportation UserChildComponent implémente OnInit { ... }
Sur la page en cours d'exécution, nous pouvons voir que le composant utilisateur-enfant est encapsulé en interne dans un ShadowDOM et que le style est également encapsulé à l'intérieur, ce qui n'affectera pas le style externe.
Angular modifie les sélecteurs CSS d'un composant afin qu'ils s'appliquent uniquement à la vue du composant et n'affectent pas les autres éléments de l'application (émulation du comportement Shadow DOM).
Lors de l'utilisation de l'encapsulation de vue fictive, Angular prétraite tous les styles de composants afin qu'ils s'appliquent uniquement à la vue du composant. Dans le DOM de l'application Angular en cours d'exécution, l'élément contenant le composant utilisant le modèle d'encapsulation de vue fictive a des attributs supplémentaires attachés :
<hero-details _nghost-pmm-5> <h3 _ngcontent-pmm-5>Monsieur Fantastique</h3> <équipe-héros _ngcontent-pmm-5 _nghost-pmm-6> <h4 _ngcontent-pmm-6>Équipe</h4> </équipe-héros> </hero-details>
Il existe deux de ces attributs :
L'attribut | details_nghost |
---|---|
est | ajouté à l'élément qui encapsule la vue du composant , qui sera les ShadowRoots dans le wrapper natif du Shadow DOM. C'est généralement le cas de l'élément hôte du composant . |
_ngcontent | est ajouté aux éléments enfants dans les vues de composants , et ces attributs sont utilisés pour faire correspondre les éléments à leurs ShadowRoots simulés respectifs (éléments hôtes avec les attributs _nghost correspondants). |
Les valeurs exactes de ces propriétés sont un détail d'implémentation privé d'Angular. Ils sont générés automatiquement et vous ne devez pas les référencer dans le code de votre application.
Ils ciblent les styles de composants générés, qui sont injectés dans des parties du DOM :
[_nghost-pmm-5] { affichage : bloc ; bordure : 1px noir uni ; } h4[_ngcontent-pmm-6] { couleur de fond : blanc ; bordure : 1px solide #777 ; }
Ces styles sont post-traités afin que chaque sélecteur CSS soit complété par l'attribut _nghost ou _ngcontent approprié. Ces sélecteurs modifiés garantissent que les styles sont appliqués aux vues d'un composant de manière isolée et ciblée.
<p>l'enfant travaille !</p>
p{ couleur : vert ; }
@Composant({ sélecteur : 'app-child', templateUrl : './child.component.html', styleUrls : ['./child.component.scss'], encapsulation : ViewEncapsulation.Emulated }) classe d'exportation ChildComponent implémente OnInit { ... }
Le résultat du paramètre ViewEncapsulation.Emulated est qu'il n'y a pas de Shadow DOM, mais le composant est encapsulé via le mécanisme d'empaquetage de style fourni par Angular, de sorte que le style du composant ne soit pas affecté par des influences externes. Bien que le style soit toujours appliqué à l'ensemble du document, Angular crée un sélecteur [_ngcontent-oow-c11] pour p. On voit que le style que nous avons défini pour le composant a été modifié par Angular. Pour faire simple, bien qu'il s'agisse d'un style global, il n'affectera pas les styles des autres composants grâce au sélecteur automatique. Si vous ajoutez manuellement cet attribut à d'autres éléments, le style sera également appliqué à cet élément.
Angular n'applique aucune forme d'encapsulation de vue, ce qui signifie que tous les styles spécifiés pour le composant sont en fait appliqués globalement et peuvent affecter n'importe quel élément HTML présent dans l'application. Ce modèle est essentiellement le même que l'inclusion de styles dans le HTML lui-même.
parent :
<p #caption>le parent travaille !{{count}}</p> <p #caption>Premier : {{count}}</p> <span class="red-font">parent</span> <app-child></app-child>
enfant :
<div style="border: 1px solid green;"> <p>L'enfant travaille !</p> <span class="red-font">Enfant</span> </div>
p{ couleur : vert ; } .fonte-rouge { couleur : rouge ; }
@Composant({ sélecteur : 'app-child', templateUrl : './child.component.html', styleUrls : ['./child.component.scss'], encapsulation : ViewEncapsulation.None }) classe d'exportation ChildComponent implémente OnInit { ... }Utilisation
ViewEncapsulation.Native dans Angular2.
@Composant({ ..., encapsulation : ViewEncapsulation.Native }) classe d'exportation UserComponent {
Le paramètre ViewEncapsulation.Native entraîne l’utilisation de la fonctionnalité native Shadow DOM. Angular rendra le composant selon le format Shadow DOM pris en charge par le navigateur. En fait, il s’agit du dernier ViewEncapsulation.ShadowDom.
nous avons présenté trois méthodes d'encapsulation de vue angulaire et leurs caractéristiques respectives. Dans le travail quotidien, vous devez choisir quelle méthode d'encapsulation en fonction de scénarios spécifiques.