我有一个父组件:
<parent></parent>
我想用子组件填充这个组:
<parent>
<child></child>
<child></child>
<child></child>
</parent>
父模板:
<div class="parent">
<!-- Children goes here -->
<ng-content></ng-content>
</div>
子模板:
<div class="child">Test</div>
由于父组件和子组件是两个独立的组件,它们的样式被锁定在自己的范围内。
在我的父组件中,我尝试这样做:
.parent .child {
// Styles for child
}
但是.child样式没有应用到子组件。
我尝试使用styleUrls将父组件的样式表包含到子组件中,以解决范围问题:
// child.component.ts
styleUrls: [
'./parent.component.css',
'./child.component.css',
]
但这并没有帮助,我还尝试了另一种方法,将子样式表取到父样式表中,但这也没有帮助。
那么,如何样式包含在父组件中的子组件呢?
更新-最新方式
如果可以避免,就不要做。正如Devon Sans在评论中指出的那样:这个功能很可能会被弃用。
最后一次更新
从Angular 4.3.0到现在(Angular 12.x),所有尖锐的css组合子都被弃用了。Angular团队引入了一个新的组合子::ng-deep,如下所示:
演示:https://plnkr.co/edit/RBJIszu14o4svHLQt563?p=preview
styles: [
`
:host { color: red; }
:host ::ng-deep parent {
color:blue;
}
:host ::ng-deep child{
color:orange;
}
:host ::ng-deep child.class1 {
color:yellow;
}
:host ::ng-deep child.class2{
color:pink;
}
`
],
template: `
Angular2 //red
<parent> //blue
<child></child> //orange
<child class="class1"></child> //yellow
<child class="class2"></child> //pink
</parent>
`
老方法
您可以使用封装模式和/或穿孔CSS组合符>>>,/deep/和::shadow
工作示例:http://plnkr.co/edit/1RBDGQ?p=preview
styles: [
`
:host { color: red; }
:host >>> parent {
color:blue;
}
:host >>> child{
color:orange;
}
:host >>> child.class1 {
color:yellow;
}
:host >>> child.class2{
color:pink;
}
`
],
template: `
Angular2 //red
<parent> //blue
<child></child> //orange
<child class="class1"></child> //yellow
<child class="class2"></child> //pink
</parent>
`
在Angular中有几个选项可以实现这一点:
1)你可以使用深层css选择器
:host >>> .childrens {
color: red;
}
2)你也可以改变视图封装,它被设置为模拟作为默认值,但可以很容易地改变为本地使用阴影DOM原生浏览器实现,在你的情况下,你只需要禁用它
例如:“
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'parent',
styles: [`
.first {
color:blue;
}
.second {
color:red;
}
`],
template: `
<div>
<child class="first">First</child>
<child class="second">Second</child>
</div>`,
encapsulation: ViewEncapsulation.None,
})
export class ParentComponent {
constructor() {
}
}
我希望通过以下方式实现这一目标:
使用@Component将css类添加到宿主元素,并将封装设置为none。然后在组件style.css.scss中引用添加到宿主的类,这将允许我们声明只影响我们自己和我们类范围内的子类的样式。初版
@Component({
selector: 'my-component',
templateUrl: './my-component.page.html',
styleUrls: ['./my-component.page.scss'],
host: {
class: 'my-component-class'
},
encapsulation: ViewEncapsulation.None
})
结合下面的CSS (my-component.page.scss)
// refer ourselves so we are allowed to overwrite children but not global styles
.my-component-class {
// will effect direct h1 nodes within template and all h1 elements within child components of the
h1 {
color: red;
}
}
// without class "scope" will affect all h1 elements globally
h1 {
color: blue;
}
这是一个只有香草css的解决方案,没有什么花哨的,你甚至不需要!重要。我假设你不能修改子结点,否则答案就更简单了,我把答案放在最后以防万一。
当使用库中预先制作的组件时,有时需要覆盖子CSS,并且开发人员没有提供任何类输入变量。::ng-deep已弃用,encapsulation: ViewEncapsulation. jpgNone将使组件的所有CSS全局化。这里有一个简单的解决方案,这两个都不用。
事实上,我们确实需要一个全局样式,以便CSS到达子节点。我们可以把样式放到styles。CSS中或者我们可以创建一个新的CSS文件并把它添加到angular。json中的样式数组中。唯一的问题是我们需要一个特定的选择器,这样就不会针对其他元素。这是一个非常简单的解决方案-只需在html中添加一个唯一的类名,我建议在类名中使用父组件的名称,以确保它是唯一的。
父组件
<child class="child-in-parent-component"></child>
让我们假设我们想要改变child中所有按钮的背景颜色,我们确实需要实现正确的专一性以确保我们的样式优先。我们可以将!important放在所有属性的旁边,但更好的方法是重复类名,直到我们的选择器足够特定,这可能需要尝试几次。这样,其他人可以在必要时再次重写此css。
全局样式文件
.child-in-parent-component.child-in-parent-component.child-in-parent-component
button {
background-color: red;
}
或者用!important(不推荐)
.child-in-parent-component button {
background-color: red !important;
}
如果子组件可以修改
只需向组件中添加一个输入变量,并使用Angular的ngStyle指令。您可以添加多个变量来为组件的多个区域设置样式。
子组件
type klass = { [prop: string]: any } | null;
@Component({...})
export class ChildComponent {
@Input() containerClass: klass = null;
@Input() pClass: klass = null;
...
}
<div [ngStyle]="containerClass">
<p [ngStyle]="pClass">What color will I be?</p>
</div>
父组件
<child
[containerClass]="{ padding: '20px', 'background-color': 'black' }"
[pClass]="{ color: 'red' }"
>
</child>
这是创建具有动态样式的组件的预期方法。许多预制组件都有类似的输入变量。
我也有这个问题,不想使用弃用的解决方案
所以我最后得出:
在parrent
<dynamic-table
ContainerCustomStyle='width: 400px;'
>
</dynamic-Table>
子组件
@Input() ContainerCustomStyle: string;
在child In HTML div中
<div class="container mat-elevation-z8"
[style]='GetStyle(ContainerCustomStyle)' >
在代码中
constructor(private sanitizer: DomSanitizer) { }
GetStyle(c) {
if (isNullOrUndefined(c)) { return null; }
return this.sanitizer.bypassSecurityTrustStyle(c);
}
作品像预期的那样,不应该被弃用;)
要在子组件中为元素的类赋值,可以在子组件中使用@Input字符串,并将其用作模板中的表达式。下面是我们在共享Bootstrap加载按钮组件中更改图标和按钮类型的示例,而不影响它在整个代码库中的使用方式:
app-loading-button.component.html(孩子)
<button class="btn {{additionalClasses}}">...</button>
app-loading-button.component.ts
@Input() additionalClasses: string;
parent.html
<app-loading-button additionalClasses="fa fa-download btn-secondary">...</app-loading-button>