我有一个父组件:
<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',
]
但这并没有帮助,我还尝试了另一种方法,将子样式表取到父样式表中,但这也没有帮助。
那么,如何样式包含在父组件中的子组件呢?
要在子组件中为元素的类赋值,可以在子组件中使用@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>
我希望通过以下方式实现这一目标:
使用@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;
}
更新-最新方式
如果可以避免,就不要做。正如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>
`
You should not write CSS rules for a child component elements in a parent component, since an Angular component is a self-contained entity which should explicitly declare what is available for the outside world. If child layout changes in the future, your styles for that child component elements scattered across other components' SCSS files could easily break, thus making your styling very fragile. That's what ViewEncapsulation is for in the case of CSS. Otherwise, it would be the same if you could assign values to private fields of some class from any other class in Object Oriented Programming.
因此,您应该做的是定义一组可以应用于子宿主元素的类,并实现子宿主如何响应它们。
技术上可以这样做:
// child.component.html:
<span class="label-1"></span>
// child.component.scss:
:host.child-color-black {
.label-1 {
color: black;
}
}
:host.child-color-blue {
.label-1 {
color: blue ;
}
}
// parent.component.html:
<child class="child-color-black"></child>
<child class="child-color-blue"></child>
换句话说,你使用Angular +一组CSS类提供的:host伪选择器在子组件本身定义可能的子样式。然后,通过将预定义的类应用到<child>宿主元素,就可以从外部触发这些样式。