用什么代替:: ng-deep

时间:2017-10-30 21:12:34

标签: html css angular

我正在尝试将路由器插座放置的元素设置为有角度,并且要确保生成的元素的宽度为100%

从大多数回复中,我发现我应该使用::ng-deep选择器,但是从Angular的docs开始,它已被弃用。是否有替代::ng-deep

7 个答案:

答案 0 :(得分:43)

FWIW在我的研究中,我没有找到任何替代ng-deep或其他适用的替代品。这是因为,我相信,Angular团队正在推迟关于影子dom的W3C规范,该规范最初具有deep等选择器。但是,W3c已删除了该建议,但未将其替换为新建议。在此之前,我认为Angular团队会保留::ng-deep并且它的替代品可用,但由于W3C草案的待处理状态而处于弃用状态。我现在无法花时间找到备份文档,但最近我确实看到了它。

长话短说:继续使用::ng-deep及其替代方案,直到创建替代品 - 弃用只是提前通知,以便在实际变更实现时人们不会瞎了。

- 更新 -

https://drafts.csswg.org/css-scoping-1/ 如果您有兴趣,这是草案提案。看起来他们正在为阴影dom树中的元素开发一组强大的选择器;一旦获得批准,这个规范,我认为将通知角度克隆,如果有一个(即角度可能不需要实现自己的选择器一旦它在浏览器中生效)。

答案 1 :(得分:8)

要绕开已弃用的::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时,您必须特别注意css选择器,并注意p和q(也许可以在Angular应用中添加子选择器,然后添加其样式)。

由于上述段落,我说这不是最好的方法,但这对我很有帮助。

答案 2 :(得分:2)

这不是:: 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

答案 3 :(得分:1)

深度样式的简单替代方法是使用父组件的元素选择器的常用样式。因此,如果您在hero-details.component.css中具有此功能:

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

在styles.css中会变成这样:

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

从本质上讲,深层样式是未封装的样式,因此从概念上讲,它对我来说更像是一种通用样式,而不是组件样式。我个人不再使用深样式。重大更改是主要版本更新中的正常现象,而过时的功能删除则是公平的游戏。

答案 4 :(得分:1)

正如之前所说,如果您使用的是第三方库,几乎不可避免地需要偶尔使用::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>
    同样,按照规则,每个单个SCSS文件的第一行将定位到组件容器。由于没有封装,因此您可以通过针对第三方组件的类来对其进行修改。也就是说, example.component.scss 应该类似于:
.app-example-container {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}

答案 5 :(得分:0)

为避免更改默认封装,我编写了一个辅助程序,为该组件附加了全局样式:

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);
    }
}

my-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>

答案 6 :(得分:-2)

您可以使用“ / deep /”。这是:: ng-deep替代品。

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