如何以及在哪里使用: : ng-deep?

我是角度4的新手,所以谁能解释一下如何在角度4中使用 ::ng-deep以及在哪里使用 ::ng-deep

实际上,我想覆盖来自父组件的子组件的一些 CSS 属性。而且 IE11支持吗?

谢谢你的帮助。

349848 次浏览

通常 /deep/ “shadow-piercing”组合器可以用来强制一个样式下降到 child components。这个选择器有一个别名 > > > ,现在又有一个名为: : ng-deep 的别名。

由于 /deep/ combinator已被弃用,建议使用 ::ng-deep

例如:

<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>

css

.overview {
::ng-deep {
p {
&:last-child {
margin-bottom: 0;
}
}
}
}

它将应用于子组件

使用方法

::ng-deep>>>/deep/禁用特定 CSS 规则的视图封装,换句话说,它允许访问组件 HTML 中没有的 DOM 元素。例如,如果你使用的是角度材料(或者其他类似的第三方库) ,一些生成的元素在组件的区域之外(比如 对话) ,你不能直接访问这些元素或者使用常规的 CSS 方式。如果你想改变这些元素的样式,你可以使用以下三种方法之一,例如:

::ng-deep .mat-dialog {
/* styles here */
}

现在,Angular 团队建议仅使用 模仿视图封装进行 “深”操作。

贬损

“深”操作实际上也是 但是现在还在工作,因为 Angular 提供预处理支持(今天不要急着拒绝 ::ng-deep,先看看 < 强 > 弃权惯例 )。

无论如何,在采用这种方法之前,我建议您看一下 禁用视图封装方法(这种方法也不理想,它允许您的样式泄漏到其他组件中) ,但是在某些情况下,它是一种更好的方法。如果决定禁用视图封装,强烈建议使用特定的类来避免 CSS 规则交叉,最后避免样式表中的混乱。很容易在组件的 .ts文件中禁用:

@Component({
selector: '',
template: '',
styles: [''],
encapsulation: ViewEncapsulation.None  // Use to disable CSS Encapsulation for this component
})

您可以在 这个文章中找到关于视图封装的更多信息。

确保不要错过 :host-context的解释,它在角度向导 ::ng-deep的正上方: https://angular.io/guide/component-styles。我之前一直没发现,真希望能早点发现。

当您没有编写组件并且无法访问其源代码时,通常需要使用 ::ng-deep,但是当您这样做时,:host-context可能是一个非常有用的选项。

例如,在我设计的一个组件中有一个黑色的 <h1>头文件,我希望能够在它显示在黑色主题背景时将其更改为白色。

如果我没有访问源代码,我可能不得不在 css 中为父代做这件事:

.theme-dark widget-box ::ng-deep h1 { color: white; }

但是,与 :host-context相反,你可以这样做 在里面的组件。

 h1
{
color: black;       // default color


:host-context(.theme-dark) &
{
color: white;   // color for dark-theme
}


// OR set an attribute 'outside' with [attr.theme]="'dark'"


:host-context([theme='dark']) &
{
color: white;   // color for dark-theme
}
}

这将查看 .theme-dark组件链中的任何位置,如果找到,则将 css 应用于 h1。这是过度依赖 ::ng-deep的一个很好的替代方案,虽然 ::ng-deep通常是反模式的。

在这种情况下,&h1代替(这就是 sass/scss 的工作原理) ,这样你就可以定义你的“正常”和主题/替代的 css,这是非常方便的。

小心得到正确的 :数字。对于 ::ng-deep有两个,而对于 :host-context只有一个。

最新消息:

您应该使用 ::ng-deep而不是 /deep/,因为 /deep/似乎已经过时了。

每份文件:

阴影穿透后代结合器已被废弃,支持为 从主要的浏览器和工具中删除。因此,我们计划 支持角度(对于/deep/,> > > 和: : ng-deep 的所有3个)。直到 然后: : ng-deep 应该是首选的,这样可以更广泛地兼容 工具

你可以找到它 给你

我想强调的是,通过要求父类是封装的 css 类,将 ::ng-deep限制为组件的唯一子类的重要性。

为了实现这一点,在父类之后使用 ::ng-deep非常重要,否则在加载组件时,它将应用于所有具有相同名称的类。

::ng-deep之前使用 :host关键字将自动处理这个问题:

:host ::ng-deep .mat-checkbox-layout

或者,您也可以通过在 ::ng-deep关键字之前添加一个组件作用域的 CSS 类来实现相同的行为:

.my-component ::ng-deep .mat-checkbox-layout {
background-color: aqua;
}

组件模板:

<h1 class="my-component">
<mat-checkbox ....></mat-checkbox>
</h1>

然后,生成的 css 将包含唯一生成的名称,并且只应用于它自己的组件实例:

.my-component[_ngcontent-c1] .mat-checkbox-layout {
background-color: aqua;
}

使用方法: : ng-deep (小心)。我在整个应用程序中使用它来设置材质设计工具栏的颜色为不同的颜色,结果发现当应用程序在测试工具栏颜色时,它们相互踩在了一起。后来发现这是因为这些样式变得全局化了,参见 这篇文章这里有一个工作代码解决方案,它不会渗入到其他组件中。

<mat-toolbar #subbar>
...
</mat-toolbar>


export class BypartSubBarComponent implements AfterViewInit {
@ViewChild('subbar', { static: false }) subbar: MatToolbar;
constructor(
private renderer: Renderer2) { }
ngAfterViewInit() {
this.renderer.setStyle(
this.subbar._elementRef.nativeElement, 'backgroundColor', 'red');
}


}

我查看了所有这些答案,发现没有人提到子组件可以从其父组件传递样式 CSS。

在组件 ts 文件中,可以使用以下命令:

   @Input() styles: any = {};

在组件 html 文件中,使用以下命令:

[ngStyle]="styles"

在父母方面,你可以这样做:

<yourComponent [styles]="{backgroundColor: 'blue', 'font-size': '16px'}">

详情请浏览这里: 将样式传递给组件的最佳方法

通过这种方式,我们没有破坏封装,而封装是最重要的面向对象原则之一