是否有某种方法可以将css动态应用于我的子组件?
我有一个可重用的组件。该组件从父组件多次调用,有时父组件的背景页为白色,有时为黑色 My child组件动态生成表单标记-输入、选择、文本区域 这意味着在我的内容组件中,css中不能有是否有某种方法可以将css动态应用于我的子组件?,css,angular,Css,Angular,我有一个可重用的组件。该组件从父组件多次调用,有时父组件的背景页为白色,有时为黑色 My child组件动态生成表单标记-输入、选择、文本区域 这意味着在我的内容组件中,css中不能有固定的样式 因此,当背景页面为白色时,我有一种输入样式,例如黑色背景。当背景页面为黑色时,我有另一种输入样式-例如白色Baggrkound 要解决这个问题,需要: 我试过了 在我的子组件ts文件中添加输入属性 @Input() public cssTemplate; 在html中 <div
固定的样式
因此,当背景页面为白色时,我有一种输入样式,例如黑色背景。当背景页面为黑色时,我有另一种输入样式-例如白色Baggrkound
要解决这个问题,需要:
我试过了
在我的子组件ts文件中添加输入属性
@Input()
public cssTemplate;
在html中
<div [ngClass]="{'form-group-white-bg': cssTemplate == 'white', 'form-group-dark-bg': cssTemplate == 'black'}">
<label for=""></label>
....
....
在子组件中,我根据调用子组件的位置发送输入属性的值
如果在白色背景的页面上调用
<app-form-group cssTemplate="black" formControlName="address">
</app-form-group>
如果它是在黑色的巴格孔德上调用的
<app-form-group cssTemplate="white" formControlName="address" [data]="{ field: 'address', label: 'Address' }">
</app-form-group>
但这里的问题是,有时在我的父组件上,这个组件被称为乘法
在一个页面上可以调用12次,其中我需要10个输入和2个选择
在其他页面上可以调用15次等
这意味着我需要重新包装自己15次
<app-form-group cssTemplate="white" formControlName="address">
</app-form-group>
<app-form-group cssTemplate="white" formControlName="someItherControlName">
</app-form-group>
到处都可以放置cssTemplate=“white”
ngFor
不是选项,因为此子组件被称为乘法,但不在父组件的HTML结构中的同一位置
如何解决此问题?您可以在styles.css(适用于所有应用程序的常规样式)中添加样式。如果你有
.white h1{
color:red;
}
.black h1{
color:green;
}
您可以在“父级”中使用[ngClass]
这允许“扩展”组件-在stackblitz中变量“主题”更改-
[1] :您可以使用输入属性创建css类映射以传递给ngClass。此对象应该是字符串数组的对象。
它可以非常复杂,包含您需要的任意多的类和规则
@输入()颜色:“白色”|“红色”|“热粉色”=“白色”;
类图:任意;
恩戈尼尼特(){
this.updateClassMap();
}
updateClassMap(){
this.classMap={
[this.color]:!!this.color,//如果不为null,则添加此类
};
}
然后在Html中,只需将其传递给ngClass
根据父组件设置子组件的样式
在这种情况下,我通常采用两种方法
:ng deep-基于父组件中设置的类创建样式规则
利用@ContentChildren()
直接在子组件上设置属性,并在更改后手动调用detectChanges()
要采用第一种解决方案,您需要在css命名规则中更加小心,因为使用ng deep显然打破了这些样式规则的隔离
采用第二种方法需要一些考虑,因为它在技术上绕过了角度上的标准输入/输出流,因此对于应用程序的任何其他维护人员来说,可能有点意外的“未记录行为”
我有点犹豫是否我更喜欢一种方法而不是另一种。第一种方法对我来说似乎更微不足道,但它也可能导致意外的样式规则覆盖,而第二种方法涉及更多的脚本编写,看起来有点像黑客
方法1:ng deep
为父组件提供输入,并更新包装
的块元素上的类
在子组件中创建所需的样式规则
//父组件
@组件(…)
导出类FooParent{
@输入()bgStyle:'light'|'dark'='light';
}
//child.css
::ng deep.light.child容器{
背景颜色:浅蓝色;
}
::ng深。深。子容器{
背景颜色:皇家蓝;
}
在示例中,我的目标元素是.child container
,您可以为要影响的每个元素编写类似的样式规则
方法2:使用ContentChildren传递值
将@ContentChildren()
装饰器添加到为子组件选择的父组件
插入一个ChangeDetectorRef
实现ngAfterViewInit以循环遍历每个子级并设置值
完成后调用detectChanges()
像在子组件中一样添加ngClass
指令
父母亲
@组件({
选择器:'父',
templateUrl:'parent.component.html',
样式URL:['parent.component.scss']
})
导出类ParentComponent实现AfterViewInit,OnChanges{
@输入()bgStyle:'light'|'dark'='light';
@ContentChildren(ChildComponent)childComponents!:QueryList;
构造函数(私有更改:ChangeDetectorRef){
}
ngOnChanges(更改:SimpleChanges){
如果('bgStyle'在更改中){
this.updateChildComponents();
}
}
updateChildComponents(){
this.childComponents.forEach(child=>{
child.bgStyle=this.bgStyle;
});
this.change.detectChanges();
}
ngAfterViewInit(){
this.updateChildComponents();
}
}
用法
注意:如果直接在ParentComponent
自己的模板中创建ChildComponent
,您需要使用@ViewChildren
而不是@ContentChildren
Tnx来进行响应。但是我仍然需要在每个子组件调用中传递cssTemplate=“white”
,以判断它是白色还是黑色。这是我的问题,而不是css。为什么?如果使用styles.css,则样式将应用于所有应用程序。这样做的目的是让您的子组件的样式“窗体组白色背景”和“窗体组黑色背景”。我想会的
<div [ngClass]="toogle?'white':'black'">
<hello name="{{ name }}"></hello>
</div>
<button (click)="toogle=!toogle">toogle</button>
@Directive({
selector: 'hello', //<--the selector is the selector of the component
exportAs: 'helloDiv'
})
export class HelloDirective implements OnInit{
constructor(@Self() private component:HelloComponent,private dataService:DataService){
}
ngOnInit(){
console.log(this.component.name)
this.dataService.theme.subscribe(res=>{
this.component.theme=res;
})
}
}
<!-- parent.component.html -->
<ng-content></ng-content>
<!-- child.component.html -->
<div [ngClass]="{light: bgStyle == 'light', dark: bgStyle == 'dark'}" class="child-container"></div>