我有一个父组件:
<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',
]
但这并没有帮助,我还尝试了另一种方法,将子样式表取到父样式表中,但这也没有帮助。
那么,如何样式包含在父组件中的子组件呢?
截至目前(Angular 9), Angular使用Shadow DOM将组件显示为自定义HTML元素。为这些自定义元素设置样式的一种优雅方法可能是使用自定义CSS变量。下面是一个通用的例子:
class ChildElement extends HTMLElement {
constructor() {
super();
var shadow = this.attachShadow({mode: 'open'});
var wrapper = document.createElement('div');
wrapper.setAttribute('class', 'wrapper');
// Create some CSS to apply to the shadow dom
var style = document.createElement('style');
style.textContent = `
/* Here we define the default value for the variable --background-clr */
:host {
--background-clr: green;
}
.wrapper {
width: 100px;
height: 100px;
background-color: var(--background-clr);
border: 1px solid red;
}
`;
shadow.appendChild(style);
shadow.appendChild(wrapper);
}
}
// Define the new element
customElements.define('child-element', ChildElement);
/* CSS CODE */
/* This element is referred as :host from the point of view of the custom element. Commenting out this CSS will result in the background to be green, as defined in the custom element */
child-element {
--background-clr: yellow;
}
<div>
<child-element></child-element>
</div>
从上面的代码中可以看到,我们创建了一个自定义元素,就像Angular为每个组件所做的那样,然后我们从全局作用域覆盖自定义元素阴影根中的背景颜色变量。
在Angular应用中,这可能是这样的:
parent.component.scss
child-element {
--background-clr: yellow;
}
child-element.component.scss
:host {
--background-clr: green;
}
.wrapper {
width: 100px;
height: 100px;
background-color: var(--background-clr);
border: 1px solid red;
}
你不应该使用::ng-deep,它已被弃用。在Angular中,从父组件中改变子组件样式的正确方法是使用封装(阅读下面的警告以了解其含义):
import { ViewEncapsulation } from '@angular/core';
@Component({
....
encapsulation: ViewEncapsulation.None
})
然后,你就可以修改组件的css,而不需要使用::ng-deep
.mat-sort-header-container {
display: flex;
justify-content: center;
}
警告:这样做将使您为该组件编写的所有css规则都是全局的。
为了将你的css的范围限制在这个组件和他的子组件上,在你的组件的顶部标签上添加一个css类,并把你的css“放在”这个标签里:
模板:
<div class='my-component'>
<child-component class="first">First</child>
</div>,
Scss文件:
.my-component {
// All your css goes in there in order not to be global
}
如果您希望更针对实际的子组件,则应该执行以下操作。这样,如果其他子组件共享相同的类名,它们也不会受到影响。
砰砰作响:
https://plnkr.co/edit/ooBRp3ROk6fbWPuToytO?p=preview
例如:
import {Component, NgModule } from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
@Component({
selector: 'my-app',
template: `
<div>
<h2>I'm the host parent</h2>
<child-component class="target1"></child-component><br/>
<child-component class="target2"></child-component><br/>
<child-component class="target3"></child-component><br/>
<child-component class="target4"></child-component><br/>
<child-component></child-component><br/>
</div>
`,
styles: [`
/deep/ child-component.target1 .child-box {
color: red !important;
border: 10px solid red !important;
}
/deep/ child-component.target2 .child-box {
color: purple !important;
border: 10px solid purple !important;
}
/deep/ child-component.target3 .child-box {
color: orange !important;
border: 10px solid orange !important;
}
/* this won't work because the target component is spelled incorrectly */
/deep/ xxxxchild-component.target4 .child-box {
color: orange !important;
border: 10px solid orange !important;
}
/* this will affect any component that has a class name called .child-box */
/deep/ .child-box {
color: blue !important;
border: 10px solid blue !important;
}
`]
})
export class App {
}
@Component({
selector: 'child-component',
template: `
<div class="child-box">
Child: This is some text in a box
</div>
`,
styles: [`
.child-box {
color: green;
border: 1px solid green;
}
`]
})
export class ChildComponent {
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App, ChildComponent ],
bootstrap: [ App ]
})
export class AppModule {}
希望这能有所帮助!
codematrix
我发现如果你可以访问子组件代码,传递@INPUT变量会更简洁:
这个想法是,父进程告诉子进程它的外观状态应该是什么,而子进程决定如何显示这个状态。这是一个很好的建筑
SCSS道:
.active {
::ng-deep md-list-item {
background-color: #eee;
}
}
更好的方法:-使用选定的变量:
<md-list>
<a
*ngFor="let convo of conversations"
routerLink="/conversations/{{convo.id}}/messages"
#rla="routerLinkActive"
routerLinkActive="active">
<app-conversation
[selected]="rla.isActive"
[convo]="convo"></app-conversation>
</a>
</md-list>