Что использовать вместо :: ng-deep

Я пытаюсь создать элемент, размещенный в розетке маршрутизатора, в угловом выражении и хочу удостовериться, что генерируемый элемент получает ширину 100%

Из большинства ответов я вижу, что я должен использовать селектор ::ng-deep, но из Angular docs он устарел. Есть ли альтернатива ::ng-deep?

Ответы

Ответ 1

FWIW В своем исследовании я не нашел замены для ng-deep или других применимых альтернатив. Это потому, что, я полагаю, команда Angular придерживается спецификации W3C для теневого домена, у которого изначально были такие селекторы, как deep. Однако с тех пор W3c удалил рекомендацию, но не заменил ее новой. До тех пор, пока это не произойдет, я представляю, что команда Angular будет держать ::ng-deep и имеющиеся альтернативы, но в устаревшем состоянии из-за отложенного состояния черновиков W3C. Я не могу найти время, чтобы найти документацию, подтверждающую это прямо сейчас, но я видел это недавно.

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

- ОБНОВЛЕНИЕ -

https://drafts.csswg.org/css-scoping-1/ Вот черновик предложения, если вы заинтересованы. Похоже, что они работают над надежным набором селекторов для элементов в дереве теневого домена; Я думаю, что именно эта спецификация, как только она будет одобрена, будет сообщать угловому клону, если он есть (например, в angular может не потребоваться реализация своих собственных селекторов, как только он будет запущен в браузерах).

Ответ 2

Чтобы обойти устаревший ::ng-deep, я обычно отключаю ViewEncapsulation. Хотя это не лучший подход, он хорошо мне послужил.

Чтобы отключить ViewEncapsulation, выполните следующие действия в своем компоненте:

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss'],
  encapsulation: ViewEncapsulation.None
})

export class HeaderComponent {

}

Это сделает стили .scss в этом компоненте глобальными для всего приложения. Чтобы не позволить стилям перейти по цепочке к родительским и родственным компонентам, оберните весь scss с помощью селектора следующим образом:

app-header {
  // your styles here and any child component styles can go here
}

Теперь указанные здесь стили будут переходить к дочерним компонентам, поэтому вам нужно быть более конкретными с вашими селекторами css и учитывать ваши p и q при добавлении CSS (возможно, добавьте дочерний селектор, указанный в вашем приложении Angular, а затем его стили).

Я говорю, что это не лучший подход из-за параграфа выше, но это мне хорошо послужило.

Ответ 3

Простая и легкая альтернатива глубокому стилю - это общий стиль, использующий селектор элементов родительского компонента. Так что, если у вас есть это в hero-details.component.css:

:host ::ng-deep h3 {
  font-style: italic;
}

Это станет таким в styles.css:

app-hero-details h3 {
  font-style: italic;
}

По сути, глубокий стиль - это неинкапсулированный стиль, поэтому концептуально он мне кажется скорее общим стилем, чем стилем компонентов. Лично я бы больше не использовал глубокие стили. В основных версиях обновлений обычно происходят критические изменения, а удаление устаревших функций - это честная игра.

Ответ 4

Это не общая замена для :: ng-deep, но для варианта использования, описанного автором вопроса:

В особом случае, когда вы хотите стилизовать элемент, вставляемый маршрутизатором-розеткой, есть элегантное решение, использующее селектор соседних соседей в CSS:

router-outlet+* {
  /* styling here... */
}

Это будет применяться ко всем элементам, которые являются прямыми соседями маршрутизатора-розетки.

Дальнейшее чтение:
https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator
https://angular.io/guide/router#router-outlet

Ответ 6

Как кто-то сказал ранее, если вы используете стороннюю библиотеку, практически невозможно избежать использования ::ng-deep время от времени. Но что вы собираетесь делать со своими предыдущими проектами, когда ::ng-deep больше не поддерживается браузерами?

Чтобы быть готовым к этому моменту, я предложу следующее:

  1. Используйте ViewEncapsulation.None с умом. Что означает только те компоненты, которым требуется доступ к более глубоким компонентам.
@Component({
      selector: 'app-example',
      templateUrl: './example.component.html',
      styleUrls: ['./example.component.scss'],
      encapsulation: ViewEncapsulation.None
    })
  1. Теперь, чтобы избежать коллизий и странностей CSS, вы должны (как правило) всегда оборачивать шаблон компонента классом. Итак, example.component.html должен выглядеть так:
<section class="app-example-container">
<!-- a third party component -->
<mat-tab-group>
<mat-tab label="First"></mat-tab>
<mat-tab label="Second"></mat-tab>
</mat-tab-group>
</section>
  1. Опять же, по правилу, первая строка каждого отдельного файла SCSS будет нацелена на контейнер компонента. Поскольку нет инкапсуляции, вы можете изменять сторонние компоненты, ориентируясь на их классы. Скажем, example.component.scss должен выглядеть следующим образом:
.app-example-container {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}