Разница между ViewEncapsulation.Native, ViewEncapsulation.None и ViewEncapsulation.Emulated
Может кто-нибудь объяснить, в чем разница между ViewEncapsulation.Native, ViewEncapsulation.None и ViewEncapsulation.Emulated в angular2.
Я пытался гуглить и читать некоторые статьи, но я не могу понять разницу.
Ниже у меня есть два компонента Home (home.ts), то есть родительский компонент и MyComp (my-comp.ts). Я хочу определить стили в родительском, которые используются в дочернем компоненте.
Должен ли я использовать ViewEncapsulation.Native или ViewEncapsulation.None
home.ts
import {Component, ViewEncapsulation} from 'angular2/core';
import {MyComp} from './my-comp';
@Component({
selector: 'home', // <home></home>
providers: [
],
directives: [
MyComp
],
styles: ['
.parent-comp-width {
height: 300px;
width: 300px;
border: 1px solid black;
}
'],
template:'
<my-comp></my-comp>
<div class="parent-comp-width"></div>
',
encapsulation: ViewEncapsulation.Native
})
export class Home {
}
мой-comp.ts
import {Component} from 'angular2/core';
@Component({
selector: 'my-comp', // <home></home>
template: '
<div class="parent-comp-width">my-comp</div>
'
})
export class MyComp {
}
Ответы
Ответ 1
Обновление
Если вы хотите добавить стили, добавленные в Parent
к Child
, вам нужно установить ViewEncapsulation.None
в компонент Child
, чтобы он не предотвращал удаление стилей.
Emulated
и Native
- это всего лишь два разных способа предотвращения стирания входы и выходы из компонентов. None
- единственный, который позволяет стилям пересекать границы компонентов.
оригинальный
-
ViewEncapsulation.None просто не инкапсуляция
-
ViewEncapsulation.Emulated(в настоящее время значение по умолчанию в Angular2)
добавляет атрибуты к тегам компонентов и дочерним элементам и манипулирует CSS (добавлением атрибутов к селекторам), добавленным на страницу, чтобы стили не сливались друг с другом - чтобы сохранить стили, привязанные к компонентам, где они добавлены, даже если стили все добавляются в заголовке страницы при загрузке компонентов.
-
ViewEncapsulation.Native создает пользовательские элементы с теневым DOM, где встроенная реализация браузеров обеспечивает определение стиля.
Если браузер не поддерживает функцию shadow DOM изначально, полиполки веб-компонентов должны продерживать поведение. Это похоже на ViewEncapsulation.Emulated
, но полиполны дороже, потому что они polyfill много API-интерфейсов браузера, даже когда большинство из них никогда не используются. Эмуляция углов Emulated
просто добавляет затраты на то, что она использует, и поэтому намного эффективнее для приложений Angular.
Ответ 2
Рассмотрим следующий ниже код. Здесь у нас есть стиль CSS ( "тест" ), который определяется как глобальный (index.html), так и inline (app.component.ts). Давайте посмотрим, как ведет себя DOM при переключении нескольких свойств ViewEncapsulation:
Пример кода:
//index.html
....
<style>
.test {background: green;}
</style>
....
<body>
<div class="test">Test!</div>
<my-app>
Loading...
</my-app>
</body>
....
//app.component.ts
@Component({
selector: 'my-app',
encapsulation: ViewEncapsulation.Emulated,
styles: [`
.test {
padding: 40px;
}
`],
template: `
<div class="test">
<div> Title: {{ title }} </div>
<input type="text" [(ngModel)]="title">
</div>
`
})
а. ViewEncapsulation.Emulated(по умолчанию)
- Генерирует _nghost и _ngcontent как атрибуты и css, такие как .test [_ngcontent-cmy-1]. это эмуляция инкапсулированных стилей, так как Angular генерирует уникальные ключи контента для компонента, которые сопоставляются с свойствами CSS. Это мощно!
- Итак, если у нас есть противоречивое свойство css, он всегда будет использовать один определенный внутри компонентный файл не глобальный
- Если не конфликтует, он будет использовать глобальный стиль для этого класса + встроенный стиль из компонента
- Это означает, что CSS, который мы пишем глобально, наследует, однако стили, определенные с использованием одного и того же класса внутри Компонента, будут локально привязаны только к этому компоненту.
б. ViewEncapsulation.Native
- Он не будет использовать глобальные атрибуты css для этого класса.
- Значит, что CSS, который мы пишем глобально, не наследует, однако стили, определенные с использованием одного и того же класса внутри Компонента, будут локально привязаны только к этому компоненту, что точно соответствует ожидаемому с помощью Shadow DOM.
-
Он генерирует теневое dom, которое подобно DOM внутри DOM, и что dom, созданный с помощью Angular, защищен, а все внутри ▾ # shadow-root - это Shadow DOM, сам по себе и отдельное дерево DOM. Именно поэтому стили arent наследуют!
-
Таким образом, он всегда будет использовать компонентный стиль, независимо от того, конфликтует или нет.
с. ViewEncapsulation.None
-
Это означает, что CSS, который мы пишем глобально, наследует, однако стили, определенные с использованием одного и того же класса внутри Компонента, переопределяют существующий стиль.
-
Ничего особенного здесь
Ответ 3
- Родной: Использует родной браузер Shadow DOM. Проверьте поддержку браузера перед включением.
- ShadowDom: использует собственные браузеры Shadow DOM v1 для лучшей кросс-браузерной поддержки и является общим стандартом для всех браузеров. Проверьте разницу между Shadow DOM v0 и v1.
- Эмулируемый: имитирует поведение Shadow DOM для определения области CSS для компонента и добавляет к голове.
- None: ни Shadow DOM, ни пользовательская реализация, как глобальный CSS, который добавляется к голове
Angular использует ViewEncapsulation.Emulated в качестве режима инкапсуляции по умолчанию.
Ответ 4
Если кто-то добирается до этого вопроса, потому что хочет стилизовать дочерние компоненты через декларации стиля родительского компонента, см. этот ответ SO.
Однако, как показывает последний комментарий к принятому ответу, Angular docs говорят:
Тень-пронизывающий комбинатор потомков устарел, а поддержка удаляются из основных браузеров и инструментов. Таким образом, мы планируем отказаться поддержка в Angular (для всех 3/глубинных/, → > и:: ng-deep). До то: ng-deep следует предпочесть для более широкой совместимости с инструменты.
Ответ 5
из про-угловой книги:
Значения ViewEncapsulation:
-
Эмуляция: если указано это значение, Angular эмулирует Shadow DOM, записывая содержимое и стили для добавления атрибутов. Это поведение по умолчанию, если не указано значение инкапсуляции.
Если вы осмотрите DOM с помощью инструментов разработчика браузеров F12, вы увидите, что содержимое внешнего CSS файла.
...
<style>
div[_ngcontent-c0] {
background-color: lightcoral;
}
</style>
...
Селектор был изменен так, чтобы он соответствовал элементам div с атрибутом _ngcontent-c0
хотя вы можете увидеть другое имя в вашем браузере, так как имя атрибута динамически генерируется Angular.
Чтобы гарантировать, что CSS в элементе style влияет только на элементы HTML, управляемые компонентом, элементы в шаблоне модифицируются таким образом, чтобы они имели один и тот же динамически генерируемый атрибут, например так:
...
<div _ngcontent-c0="" class="form-group">
<label _ngcontent-c0="">Name</label>
<input _ngcontent-c0="" class="form-control ng-untouched ng-pristineng-invalid"
ng-reflect-name="name" name="name">
</div>
...
- Собственный: Когда указано это значение, Angular использует функцию DOM браузера. Это будет работать, только если в браузере реализован теневой DOM или если вы используете полифилл.
- None: если указано это значение, Angular просто добавляет неизмененные стили CSS в раздел head документа HTML и позволяет браузеру выяснить, как применять стили с помощью обычных правил приоритета CSS.
Значения Native и None следует использовать с осторожностью. Браузерная поддержка функции теневого DOM настолько ограничена, что использование параметра Native целесообразно только в том случае, если вы используете библиотеку polyfill, которая обеспечивает совместимость с другими браузерами.
Опция None добавляет все стили, определенные компонентами, в раздел head документа HTML и позволяет браузеру выяснить, как их применять. Это дает преимущество работы во всех браузерах, но результаты непредсказуемы, и нет никакой изоляции между стилями, определенными различными компонентами.
Ответ 6
Пожалуйста, обратитесь к примеру ниже, чтобы понять все три варианта:
encapsulation: ViewEncapsulation.Emulated
encapsulation: ViewEncapsulation.Native
encapsulation: ViewEncapsulation.None
Нажмите здесь, чтобы увидеть пример