Я новичок в Angular 4, так что может кто-нибудь объяснить, как и где использовать :: ng-deep в Angular 4?

На самом деле я хочу перезаписать некоторые свойства CSS дочерних компонентов из родительских компонентов. Более того, поддерживается ли он в IE11?

Спасибо за помощь.

Ответы (6)

Обычно / deep / «shadow-piercing» комбинатор может использоваться для принудительного уменьшения стиля до дочерних компонентов. У этого селектора был псевдоним >>>, а теперь есть еще один - :: ng-deep.

поскольку / deep / combinator устарел, рекомендуется использовать :: ng-deep

Например:

и css

.overview {
    ::ng-deep {
        p {
            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}

будет применяться к дочерним компонентам

Я бы подчеркнул важность ограничения :: ng-deep только дочерними элементами компонента, требуя, чтобы родитель был инкапсулированным классом css.

Чтобы это работало, важно использовать :: ng-deep после родителя, а не до того, как в противном случае он будет применяться ко всем классам с тем же именем в момент загрузки компонента.

Использование ключевого слова : host перед :: ng-deep обработает это автоматически:

:host ::ng-deep .mat-checkbox-layout

В качестве альтернативы вы можете добиться того же поведения, добавив класс CSS с компонентной областью видимости перед ключевым словом :: ng-deep:

.my-component ::ng-deep .mat-checkbox-layout {
    background-color: aqua;
}

Шаблон компонента:


Результирующий (сгенерированный на Angular) css будет включать уникально сгенерированное имя и применяться только к собственному экземпляру компонента:

.my-component[_ngcontent-c1] .mat-checkbox-layout {
    background-color: aqua;
}

ИСПОЛЬЗОВАНИЕ

:: ng-deep, >>> и / deep / отключает инкапсуляцию представления для определенных правил CSS, другими словами, это дает вам доступ в элементы DOM, которых нет в HTML вашего компонента. Например, если вы используете Angular Material (или любую другую подобную стороннюю библиотеку), некоторые сгенерированные элементы находятся за пределами области вашего компонента (например, dialog), а вы не может получить доступ к этим элементам напрямую или с помощью обычного метода CSS. Если вы хотите изменить стили этих элементов, вы можете использовать одну из этих трех вещей, например:

::ng-deep .mat-dialog {
  /* styles here */
}

На данный момент команда Angular рекомендует делать «глубокие» манипуляции только с EMULATED инкапсуляцией представления.

УДАЛЕНИЕ

«глубокий» манипуляции на самом деле устарели тоже, НО он все еще работает, потому что Angular поддерживает предварительную обработку (не спешите отказываться от :: ng-deep сегодня, взгляните на методы устаревания сначала).

В любом случае, прежде чем идти по этому пути, я рекомендую вам взглянуть на отключение инкапсуляции представления (который тоже не идеален, он позволяет вашим стилям проникать в другие компоненты), но в некоторых случаях , это лучший способ. Если вы решили отключить инкапсуляцию представления, настоятельно рекомендуется использовать определенные классы, чтобы избежать пересечения правил CSS и, наконец, избежать беспорядка в ваших таблицах стилей. Отключить действительно просто прямо в файле .ts компонента:

@Component({
  selector: '',
  template: '',
  styles: [''],
  encapsulation: ViewEncapsulation.None  // Use to disable CSS Encapsulation for this component
})

Дополнительную информацию об инкапсуляции представления можно найти в этой статье.

Не пропустите объяснение : host-context, которое находится прямо над :: ng-deep в угловом руководстве: https://angular.io/guide/component-styles. Я пропустил это до сих пор и хотел бы увидеть его раньше.

:: ng-deep часто требуется, когда вы не писали компонент и не имеете доступа к его источнику, но : host-context может быть очень полезная опция, когда вы это сделаете.

Например, у меня есть черный

заголовок внутри компонента, который я разработал, и мне нужна возможность изменить его на белый, когда он отображается на темном тематическом фоне.

Если бы у меня не было доступа к источнику, мне, возможно, пришлось бы сделать это в CSS для родителя:

.theme-dark widget-box ::ng-deep h1 { color: white; }

Но вместо этого с : host-context вы можете сделать это внутри компонента.

 h1 
 {
     color: black;       // default color

     :host-context(.theme-dark) &
     {
         color: white;   // color for dark-theme
     }

     // OR set an attribute 'outside' with [attr.theme]="'dark'"

     :host-context([theme='dark']) &
     {
         color: white;   // color for dark-theme
     }
 }

Это будет искать в любом месте цепочки компонентов для .theme-dark и применять CSS к h1, если он найден. Это хорошая альтернатива чрезмерной зависимости от :: ng-deep, который, хотя и часто необходим, является своего рода анти-шаблоном.

В этом случае & заменяется h1 (так работает sass / scss), поэтому вы можете определить свой «нормальный» и тематический / альтернативный CSS рядом с каждым другое, что очень удобно.

Будьте осторожны, чтобы получить правильное число :. Для :: ng-deep их два, а для : host-context только один.

Используйте :: ng-deep с осторожностью. Я использовал его во всем своем приложении, чтобы настроить цвет панели инструментов материального дизайна на разные цвета во всем моем приложении, только чтобы обнаружить, что, когда приложение тестировало, цвета панели инструментов накладываются друг на друга. Чтобы понять, что это происходит из-за того, что эти стили становятся глобальными, см. в этой статье Вот рабочий код решения, который не просачивается в другие компоненты.


...


export class BypartSubBarComponent implements AfterViewInit {
  @ViewChild('subbar', { static: false }) subbar: MatToolbar;
  constructor(
    private renderer: Renderer2) { }
  ngAfterViewInit() {
    this.renderer.setStyle(
      this.subbar._elementRef.nativeElement, 'backgroundColor', 'red');
  }

}

Просто обновление:

Вы должны использовать :: ng-deep вместо / deep /, что кажется устаревшим.

Согласно документации:

Комбинатор потомков с пропусканием теней устарел, а поддержка удаляется из основных браузеров и инструментов. Таким образом, мы планируем отказаться от поддержка в Angular (для всех 3 из / deep /, >>> и :: ng-deep). До того как then :: ng-deep следует предпочесть для более широкой совместимости с инструменты.

Его можно найти здесь

2022 WebDevInsider