使用什么代替: : ng-deep

我试图风格的元素放在路由器出口的角度,并希望确保元素生成获得100% 的宽度

从大多数的回复,我看到,我应该使用 ::ng-deep选择器,但从角度的 医生是被弃用。有 ::ng-deep的替代品吗?

122998 次浏览

在我的研究中,我没有发现任何替代 ng-deep 或其他适用的替代品。这是因为,我相信,Angular 团队正在遵从 W3C 规范的阴影王国,最初有选择器,如 deep。然而,W3c 已经删除了这个建议,但是没有用一个新的建议来代替它。在那之前,我想 Angular 团队会保留 ::ng-deep和它的替代品,但是由于 W3C 草案的悬而未决的状态而处于弃用状态。我现在无法花时间找到文档来支持这一点,但我最近确实看到了它。

长话短说: 继续使用 ::ng-deep及其替代品,直到创建一个替代品为止——不赞成只是一个早期通知,这样人们就不会在实际变更出现时措手不及。

—— 更新——

Https://drafts.csswg.org/css-scoping-1/ 如果你感兴趣,这是建议草案。看起来他们正在为一个影子树中的元素开发一个健壮的选择器集合; 正是这个规范,一旦被批准,我认为将通知角度克隆,如果有一个(即角度可能不需要实现他们自己的选择器,一旦它在浏览器中上线)。

为了绕过废弃的 ::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 (也许添加在你的角度应用中指定的子选择器,然后它的样式)。

我说这不是最好的方法,因为上面的段落,但这对我很有用。

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

使用父组件的元素选择器的常见样式是深度样式的简单替代方法。所以如果你有这个英雄细节。Css:

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

在 styles.css 中会变成这样:

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

基本上,深层样式是一种非封装的样式,因此在我看来,它在概念上更像是一种普通样式,而不是组件样式。就个人而言,我不会再使用深度风格。在主要版本更新中,破坏性更改是正常的,而不推荐的特性删除是合理的。

如前所述,如果您使用的是第三方库,那么偶尔避免使用 ::ng-deep几乎是不可能的。

让我们看看其他的选择

  1. 使用视图封装
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss'],
encapsulation: ViewEncapsulation.None
})

请注意,打破组件的封装将使样式全局可用。我可以用两种方法来避免冲突和 CSS 的怪异:

  • 用一个类包装组件的模板:
<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>

现在,由于没有 封装,您可以通过定位第三方组件的类来修改它们。也就是说,Example.component.scss应该是这样的:

.app-example-container {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}
  • 或者使用组件的标记名作为包装器。例如:
app-example {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}
  1. 使用全局样式

只需要将一个新的 CSS 文件添加到 angular.json配置文件的样式数组中即可。请注意,这最终将变得越来越难以维护。就个人而言,我会避免这种选择,或者把它作为最后的手段:)

  1. 发出指令

我同意这有点痛苦,因为您不能包含 指令中的样式(与您可以在组件中使用相同的方法) ,但是有时它可以很方便。你也可以使用一个组件来应用样式,就像角材料团队使用 纽扣一样

  1. 主持人: : ng-deep

您已经知道了这个,只是想说明一下,将它与主机选择器一起使用是 Angular 推荐的避免潜在样式冲突的方法。

对未来的自我提示: https://angular.io/guide/component-styles
这应该是寻找官方替代方案/出路的第一步

编辑1。正如@beppe9000在评论中提到的,: : ng-deep 是一个有角度的东西。即使 Angular 团队明天删除了这个功能,你已经部署的应用程序仍将继续工作。混淆是由于旧的 /deep/修饰词引起的。

您可以使用“/deep/”。

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

如果你想设计一些第三方组件,这是在整个网站的几个地方使用,但你需要特定的 CSS 外观在一个地方不影响其他事件后访问这个网页-你可以使用 [ngStyle]。 我知道它不适合所有情况,但在我的案例中,它是一种方式(我需要有 ViewEncapsulation.None,所以我不能在单独的 CSS 文件中隔离样式)。