
В повседневной работе, когда мы определяем Component , мы должны учитывать его инкапсуляцию , то есть ожидаете ли вы, что стиль, определенный в этом компоненте, будет действовать только на этот компонент, или вы хотите, чтобы он действовал глобально. В Angular стили компонента могут быть инкапсулированы в хост-элемент компонента, чтобы они не влияли на остальную часть приложения. Декоратор компонентов предоставляет параметры инкапсуляции, которые можно использовать для управления применением инкапсуляции представления для каждого компонента. [Рекомендации по соответствующему руководству: «Учебное пособие по Angular»]
В Angular существует три режима инкапсуляции, а именно ViewEncapsulation.ShadowDom, ViewEncapsulation.Emulated и ViewEncapsulation.None.
экспортировать перечисление ViewEncapsulation {
/**
* Эмулирует собственное поведение инкапсуляции Shadow DOM, добавляя определенный атрибут в
* хост-элемент компонента и применение одного и того же атрибута ко всем предоставленным селекторам CSS
* через {@link Component#styles Styles} или {@link Component#styleUrls styleUrls}.
*
* Это опция по умолчанию.
*/
Эмулируемый = 0,
/**
* Не обеспечивает никакой инкапсуляции стилей CSS. Это означает, что все предоставленные стили
* можно использовать {@link Component#styles style} или {@link Component#styleUrls styleUrls}.
* к любому элементу HTML приложения независимо от его основного компонента.
*/
Нет = 2,
/**
* Использует собственный Shadow DOM API браузера для инкапсуляции стилей CSS, то есть создает
* ShadowRoot для хост-элемента компонента, который затем используется для инкапсуляции
* все стили компонента.
*/
ТеньДом=3
} Если не указано, значение получается из CompilerOptions. Параметр компилятора по умолчанию — ViewEncapsulation.Emulated.
Если для политики установлено значение ViewEncapsulation.Emulated, а компонент не указывает стили или styleUrls, он автоматически переключится на ViewEncapsulation.None.
Вы выяснили, почему в типе перечисления нет единицы ? Подробнее об этом позже.
Оставив в стороне инкапсуляцию ShadowDom в Angular, давайте сначала посмотрим, что такое ShadowDOM.
Теневой DOM позволяет прикрепить скрытое дерево DOM к обычному дереву DOM — оно начинается с теневого корневого узла. Ниже этого корневого узла может быть любой элемент, как и обычный элемент DOM.

Здесь есть некоторые термины, специфичные для Shadow DOM, которые нам необходимо понять:
Вы можете манипулировать теневым DOM так же, как и обычным DOM, например, добавляя дочерние узлы, устанавливая свойства и добавляя к узлу собственный стиль (например, через свойство element.style) или добавляя стили ко всему узлу. Теневой DOM (например, добавление стилей внутри элементов). Разница в том, что элементы внутри Shadow DOM никогда не будут влиять на элементы вне его (кроме :focus-within), что облегчает инкапсуляцию.
Давайте посмотрим на простой пример.
<!DOCTYPE html>
<html>
<голова>
<мета-кодировка="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, Initial-scale=1.0">
<title>Теневой DOM</title>
<стиль>
охватывать{
цвет: зеленый;
}
</стиль>
</голова>
<тело>
<span>Я root</span>
<div id="app"></div>
<скрипт>
let app = document.querySelector('#app');
letshadow1 = app.attachShadow({режим: 'open'});
пусть style1 = document.createElement('style');
style1.appendChild(document.createTextNode("span{color: red;}"));
тень1.appendChild(стиль1);
let span1 = document.createElement('span');
span1.textContent = 'Я – span.';
тень1.appendChild(диапазон1);
</скрипт>
</тело>
</html> 
В приведенном выше примере определяются глобальный стиль диапазона и стиль диапазона в ShadowDOM. Видно, что они не зависят друг от друга.
После того, как вы поняли, что такое ShadowDOM, давайте взглянем на инкапсуляцию ShadowDOM в Angular.
Angular использует встроенный в браузер API Shadow DOM для переноса представления компонента в ShadowRoot (который служит главным элементом компонента) и изолированного применения предоставленных стилей. ViewEncapsulation.ShadowDom работает только в браузерах со встроенной поддержкой теневого DOM. Не все браузеры поддерживают его, поэтому ViewEncapsulation.Emulated является рекомендуемым режимом по умолчанию.
Например, в следующем примере используйте ViewEncapsulation.ShadowDom .
@Компонент({
селектор: 'пользователь-ребенок',
templateUrl: 'UserChild.comComponent.html',
стили: [`
ч3{
цвет: красный;
}
`],
инкапсуляция: ViewEncapsulation.ShadowDom
})
класс экспорта UserChildComponent реализует OnInit {
...
} 
На работающей странице мы видим, что дочерний пользовательский компонент внутренне инкапсулирован в ShadowDOM, и стиль также инкапсулирован внутри, что не влияет на внешний стиль.
Angular изменяет селекторы CSS компонента так, чтобы они применялись только к представлению компонента и не влияли на другие элементы в приложении (эмулируя поведение Shadow DOM).
При использовании инкапсуляции макетного представления Angular предварительно обрабатывает все стили компонента, чтобы они применялись только к представлению компонента. В DOM работающего приложения Angular к элементу, содержащему компонент, использующий шаблон инкапсуляции макетного представления, прикреплены некоторые дополнительные атрибуты:
<hero-details _nghost-pmm-5>
<h3 _ngcontent-pmm-5>Мистер Фантастик</h3>
<команда героев _ngcontent-pmm-5 _nghost-pmm-6>
<h4 _ngcontent-pmm-6>Команда</h4>
</hero-team>
</hero-details> Таких атрибутов два:
| Атрибут | Details_nghost |
|---|---|
| добавляется | к элементу, который обертывает представление компонента , который будет ShadowRoots в собственной оболочке Shadow DOM. Обычно это относится к элементу хоста компонента . |
| _ngcontent | добавляется к дочерним элементам в представлениях компонентов , и эти атрибуты используются для сопоставления элементов с их соответствующими смоделированными ShadowRoots (основными элементами с соответствующими атрибутами _nghost). |
Точные значения этих свойств являются частной деталью реализации Angular. Они генерируются автоматически, и вам не следует ссылаться на них в коде приложения.
Они нацелены на сгенерированные стили компонентов, которые внедряются в части DOM:
[_nghost-pmm-5] {
дисплей: блок;
граница: 1 пиксель, сплошная черная;
}
h4[_ngcontent-pmm-6] {
цвет фона: белый;
граница: 1 пиксель, сплошная #777;
} Эти стили подвергаются постобработке, поэтому каждый селектор CSS дополняется соответствующим атрибутом _nghost или _ngcontent. Эти модифицированные селекторы гарантируют, что стили применяются к представлениям компонента изолированным и целенаправленным образом.
<p>ребенок работает!</p>
p{
цвет: зеленый;
} @Компонент({
селектор: 'app-child',
templateUrl: './child.comComponent.html',
styleUrls: ['./child.comComponent.scss'],
инкапсуляция: ViewEncapsulation.Emulated
})
класс экспорта ChildComponent реализует OnInit {
...
} 
Результатом настройки ViewEncapsulation.Emulated является отсутствие теневого DOM, но компонент инкапсулируется с помощью механизма упаковки стилей, предоставляемого Angular, поэтому на стиль компонента не влияют внешние воздействия. Хотя стиль по-прежнему применяется ко всему документу, Angular создает селектор [_ngcontent-oow-c11] для p. Видно, что стиль, который мы определили для компонента, был изменен Angular. Проще говоря, хотя это и глобальный стиль, он не повлияет на стили других компонентов благодаря автоматическому выбору. Если вы вручную добавите этот атрибут к другим элементам, стиль также будет применен к этому элементу.
Angular не применяет никакой формы инкапсуляции представления, что означает, что любые стили, указанные для компонента, фактически применяются глобально и могут повлиять на любой элемент HTML, присутствующий в приложении. По сути, этот шаблон аналогичен включению стилей в сам HTML.
родитель:
<p #caption>родитель работает!{{count}}</p>
<p #caption>Первый: {{count}}</p>
<span class="red-font">родитель</span>
<app-child></app-child> дочерний элемент:
<div style="border: 1px сплошной зеленый;">
<p>ребенок работает!</p>
<span class="red-font">Дочерний</span>
</div> р{
цвет: зеленый;
}
.red-font {
цвет: красный;
} @Компонент({
селектор: 'app-child',
templateUrl: './child.comComponent.html',
styleUrls: ['./child.comComponent.scss'],
инкапсуляция: ViewEncapsulation.None
})
класс экспорта ChildComponent реализует OnInit {
...
} 
Используйте ViewEncapsulation.Native в Angular2.
@Компонент({
...,
инкапсуляция: ViewEncapsulation.Native
})
класс экспорта UserComponent { 
Параметр ViewEncapsulation.Native приводит к использованию встроенной функции Shadow DOM. Angular будет отображать компонент в соответствии с форматом Shadow DOM, поддерживаемым браузером. Фактически это более поздний ViewEncapsulation.ShadowDom.
мы представили три метода инкапсуляции представления Angular и их соответствующие характеристики. В повседневной работе вам следует выбирать, какой метод инкапсуляции соответствует конкретным сценариям.