用什么代替:: ng-deep

Jac*_*rtz 53 html css angular

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

从大多数回复中,我看到我应该使用::ng-deep选择器,但是从Angular的文档中它被弃用了.有替代品::ng-deep吗?

dud*_*wad 63

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

简而言之:::ng-deep在创建替代品之前继续使用及其替代方案 - 弃用只是提前通知,以便在实际变更实现时人们不会瞎了眼.

- 更新 -

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

  • 使用第三方库,几乎不可能避免偶尔使用`:: ng-deep`(如果您完全关心网站的外观)-即使是像棱角分明的东西。他们有几个月无法修复的错误,解决方法通常涉及ng-deep。并且不要混淆不同的不推荐使用的'deep'选择器-`:: ng-deep`绝对是最不推荐使用的选择器。 (13认同)
  • 我也是.但是我没有别的选择,我认为这里没有明确地概述.你有什么建议可以帮忙吗? (5认同)
  • 是的,这是整个系统中最丑陋的部分之一。但封装就是封装。您必须通过在 css 中显式使用 ::ng-deep 来打破边界,或者需要以编程方式执行此操作。我们有时会在组件标签上使用属性来指示组件所处的“模式”(即上下文),然后样式可以通过属性选择器而不是 ::ng-deep 存在于子组件中,例如: `: host[some-context] {}` - 这取决于您想要什么样的灵活性/可移植性。我不太喜欢这两种方式,但这就是封装的世界。 (2认同)
  • 正在进行的讨论:[澄清有关 :ng-deep 弃用的信息并建议替换](https://github.com/angular/angular/issues/25160) 以及最近的一篇博客文章,其中包含关于 [Future of ng-deep] 的声明覆盖样式](https://blog.angular.io/the-new-state-of-css-in-angular-bec011715ee6#12af) (2认同)

J. *_*the 34

深层样式的简单易行的替代方法是使用父组件的元素选择器的常见样式。所以如果你在 hero-details.component.css 中有这个:

:host ::ng-deep h3 {
  font-style: italic;
}
Run Code Online (Sandbox Code Playgroud)

在styles.css中会变成这样:

app-hero-details h3 {
  font-style: italic;
}
Run Code Online (Sandbox Code Playgroud)

基本上,深层样式是一种未封装的样式,因此在我看来,它在概念上更像是一种普通样式,而不是组件样式。我个人不会再使用深度样式了。重大版本更新中的重大更改是正常的,不推荐使用的功能删除是公平的游戏。

  • 哇,我现在感觉很蠢。谢谢!来自其他前端框架我认为这是不可能的 (2认同)
  • 这真的很有用。遗憾的是 ::ng-deep 被弃用了这么长时间而没有替代品( :host::ng-deep 按预期工作,但我不想使用已弃用的东西)。 (2认同)
  • 我很困惑,这应该如何运作?如果您在父组件中指定“app-hero-details h3 { ... }”,它将被封装并且不会影响子组件中的 h3。如果您建议在一般共享样式中使用它,那么好吧,但我认为不应该这样做。 (2认同)

Jos*_*man 10

正如之前有人所说,如果您使用第三方库,几乎不可能避免::ng-deep偶尔使用一次。但是当::ng-deep浏览器不再支持时,您将如何处理以前的项目?

为了为那一刻做好准备,我将提出以下建议:

  1. 明智地使用ViewEncapsulation.None。这意味着仅适用于需要访问更深层次组件的那些组件。
@Component({
      selector: 'app-example',
      templateUrl: './example.component.html',
      styleUrls: ['./example.component.scss'],
      encapsulation: ViewEncapsulation.None
    })
Run Code Online (Sandbox Code Playgroud)
  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>
Run Code Online (Sandbox Code Playgroud)
  1. 同样,按照规则,每个 SCSS 文件的第一行都将针对组件容器。由于没有封装,您可以通过定位第三方组件的类来修改第三方组件。也就是说,example.component.scss应该是这样的:
.app-example-container {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}
Run Code Online (Sandbox Code Playgroud)

对未来的自我说明:https : //angular.io/guide/component-styles
这应该是寻找官方替代品/ways-to-go 的第一个地方


Ali*_*F50 9

要绕开已弃用的设备::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 {

}
Run Code Online (Sandbox Code Playgroud)

这将使此组件中的.scss样式对整个应用程序都是全局的。为了不允许样式沿着父级和同级组件向上移动,请使用选择器将整个scss包装起来,如下所示:

app-header {
  // your styles here and any child component styles can go here
}
Run Code Online (Sandbox Code Playgroud)

现在,此处指定的样式将归因于子组件,因此添加CSS时,您必须特别注意css选择器,并注意p和q(可能会添加Angular应用中指定的子选择器,然后添加其样式)。

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

  • 这只是解决方法,如果您有庞大的项目,则关闭“ ViewEncapsulation”将使这些样式可能泄漏到所有组件中,从而造成很多损害。[应该明智且充分理解地使用此功能](https://dzone.com/articles/what-is-viewencapsulation-in-angular) (10认同)
  • @mpro我了解,这就是为什么我要提出警告,并说这不是最好的方法,并且您必须注意p和q的情况,并且必须特别具体。对我来说,这种方法到目前为止效果很好。:: ng-deep被标记为弃用,这是一种解决方法。 (4认同)
  • 老实说,如果你因为威胁要弃用而这样做,我认为这是一个可怕的结论。是的,我知道你也承认这一点,但我真的认为你这样做是在搬起石头砸自己的脚。视图封装之所以如此有用,有很多原因。然而,它并不像角度团队中的任何人在没有任何逻辑解决方法的情况下弃用它那么糟糕,并导致许多人感到困惑。归根结底,您仍然在为网络浏览器编写代码,而不是某种专有的角度引擎。 (2认同)
  • @Simon_Weaver我尊重您的意见,并感谢您的分享。我只是在进行表面处理,因为这是我用来规避过时的方法。我也浮出水面。 (2认同)
  • @ AliF50“绕过绝望”不是真的。真正的问题是,而且我一生中从未见过这种情况,他们不提倡使用这种方法,而没有命名替代方法。我的答案(上面被接受的答案)解释了我的假设,即他们为什么这样做(W3C不赞成使用)以符合规范。但是,如果您阅读了这些建议,则看起来:: ng-deep将被替换为合适的替代方法,这意味着,当可用时,您只需更新:: ng-deep引用即可,而不是实际需要的方法重新架构整个应用程序。 (2认同)