在Angular 4中如何使用::ng-deep,在哪里使用?
实际上,我想从父组件中覆盖子组件的一些CSS属性。此外,IE11支持它吗?
在Angular 4中如何使用::ng-deep,在哪里使用?
实际上,我想从父组件中覆盖子组件的一些CSS属性。此外,IE11支持它吗?
当前回答
确保不要错过angular指南:https://angular.io/guide/component-styles中::ng-deep上面的:host-context的解释。直到现在我都没看到,真希望我能早点看到。
::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来说,这是一个很好的替代方案,后者虽然通常是必要的,但在某种程度上是一种反模式。
在这种情况下&被h1取代(这就是sass/scss的工作方式),所以你可以定义你的“正常”和主题/替代css,这是非常方便的。
请注意获得正确的:。对于::ng-deep有两个,而对于:host-context只有一个。
其他回答
通常/deep/ " shadow- penetrating "组合符可以用来强制一种样式到子组件。这个选择器有一个别名>>>,现在有了另一个名为::ng-deep的别名。
由于/deep/组合子已弃用,建议使用::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。我在我的应用程序中使用它来设置材质设计工具栏的颜色,在我的应用程序中,却发现当应用程序在测试工具栏的颜色时,它们会相互踩在一起。这是一个不渗透到其他组件的工作代码解决方案。
<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');
}
}
使用
::ng-deep, >>> and /deep/ disable view encapsulation for specific CSS rules, in other words, it gives you access to DOM elements, which are not in your component's HTML. For example, if you're using Angular Material (or any other third-party library like this), some generated elements are outside of your component's area (such as dialog) and you can't access those elements directly or using a regular CSS way. If you want to change the styles of those elements, you can use one of those three things, for example:
::ng-deep .mat-dialog {
/* styles here */
}
目前,Angular团队建议只使用EMULATED视图封装来进行“深度”操作。
弃用
“deep”操作实际上也被弃用了,但它现在仍然有效,因为Angular支持预处理(今天不要急于拒绝::ng-deep,先看看弃用实践)。
无论如何,在采用这种方法之前,我建议您看看禁用视图封装方法(这也不是理想的方法,它允许您的样式泄漏到其他组件中),但在某些情况下,这是一种更好的方法。如果您决定禁用视图封装,强烈建议使用特定的类来避免CSS规则的交叉,最后,避免样式表中的混乱。在组件的.ts文件中禁用它真的很容易:
@Component({
selector: '',
template: '',
styles: [''],
encapsulation: ViewEncapsulation.None // Use to disable CSS Encapsulation for this component
})
您可以在本文中找到关于视图封装的更多信息。
我浏览了所有这些答案,发现没有人提到子组件可以从父组件传递样式CSS。
在组件的文件中,你可以这样做:
@Input() styles: any = {};
在组件html文件中,你使用这个:
[ngStyle]="styles"
在parent中,你可以这样使用:
<yourComponent [styles]="{backgroundColor: 'blue', 'font-size': '16px'}">
请在这里查看更多细节:将样式传递给组件的最佳方式
通过这种方式,我们没有破坏封装,这是最重要的面向对象原则之一
更新一下:
你应该使用::ng-deep而不是/deep/,这似乎是不推荐的。
每个文档:
暗影穿透的后代组合子已弃用,支持是 从主流浏览器和工具中删除。因此,我们打算放弃 Angular中的支持(支持/deep/、>>>和::ng-deep中的所有3个)。直到 那么::ng-deep应该优先用于更广泛的兼容性 的工具。
你可以在这里找到它