Разница между 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

Нажмите здесь, чтобы увидеть пример