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

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

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

9 ответов

Решение

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

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

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

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

Это стало бы в styles.css:

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

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

Обойти устаревшее ::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, а затем его стили).

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

Как кто-то сказал ранее, если вы используете стороннюю библиотеку, практически невозможно избежать использования ::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;}
}

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

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

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

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

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

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

deepStyle.ts

import { ViewContainerRef } from '@angular/core';

export function deepStyle(vcr: ViewContainerRef, csss: string[]){
    let id = 'deep-' + vcr.element.nativeElement.tagName;
    let styleElement = document.getElementById('pierce-' + vcr.element.nativeElement.name);
    if(!styleElement){
        styleElement = document.createElement('style');
        styleElement.id = id;
        styleElement.innerHTML = csss.map(css => vcr.element.nativeElement.tagName + ' ' + css).join('\n');
        document.head.append(styleElement);
    }
}

мой-component.ts

import { Component, ViewContainerRef } from '@angular/core';
import { deepStyle } from '../deepStyle';

@Component({
  selector: 'my-component',
  templateUrl: './my-component.html',
  styleUrls: ['./my-component.css']
})
export class MyComponent {
   constructor(vcr: ViewContainerRef) {
    deepStyle(vcr, [`
       img {
         height: 180px;
       }
    `]);
  }
}

результат:

<head>
...
<style id="deep-MY-COMPONENT">
    MY-COMPONENT img {
      height: 180px;
    }
</style>
...
</head>

Если вы хотите стилизовать какой-либо сторонний компонент, который используется на сайте в нескольких местах, но вам нужен определенный вид CSS в одном месте, не влияющий на другие вхождения после посещения ЭТОЙ страницы - вы можете использовать. Я понимаю, что это не подходит для всех ситуаций, но в моем случае это выход (мне нужно иметь, поэтому я не могу изолировать стили в отдельном файле CSS).

Вы можете использовать "/deep/". Это:: глубокая альтернатива.

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

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

Прочитайте больше:

https://hackernoon.com/the-new-angular-ng-deep-and-the-shadow-piercing-combinators-deep-and-drop-4b088dbe459

Другие вопросы по тегам