【发布时间】:2019-12-06 20:21:29
【问题描述】:
我想从父级动态设置子宿主组件元素的样式。
有一个解决方案可以为每种样式单独执行:
@HostBinding('style.width') @Input() width = 'auto'
但是这样我需要为不同的样式制作多行。
Bellow 是一种通过主机绑定和输入组合来实现此目的的解决方案。
【问题讨论】:
标签: angular typescript binding components
我想从父级动态设置子宿主组件元素的样式。
有一个解决方案可以为每种样式单独执行:
@HostBinding('style.width') @Input() width = 'auto'
但是这样我需要为不同的样式制作多行。
Bellow 是一种通过主机绑定和输入组合来实现此目的的解决方案。
【问题讨论】:
标签: angular typescript binding components
ngStyle 是为此指定的。
<app-button [ngStyle]="{ marginTop: '10px', marginLeft: '50px' }">Some button</app-button>
当然,您可以将其外包给控制器,而不是像这样将其硬编码到模板中。
https://angular.io/api/common/NgStyle
PS:由于 style 已经存在于所有元素上,我不确定您的代码的行为
【讨论】:
如果您想将多个 css 样式作为字符串或作为具有 cammelCase 约定的对象传递,这是一个解决方案:
父 HTML
<app-button [style]="styleFromParent">Some button</app-button>
父组件具有styleFromParent 属性,并且如果该属性在某个时刻发生更改,它具有模拟:
父组件 TS
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-site-panel',
templateUrl: './site-panel.component.html',
})
export class SitePanelComponent implements OnInit {
constructor(private _detectChanges: ChangeDetectorRef) {}
styleFromParent = { marginTop: '10px', marginLeft: '50px' };
ngOnInit() {
setTimeout(() => {
this.styleFromParent = { marginTop: '20px', marginLeft: '1px' };
this._detectChanges.detectChanges();
}, 2000);
}
}
子 HTML
<ng-content></ng-content>
子组件 TS
如果typeof style === 'object' 是将cammelCase 样式解析为基于破折号的样式并将它们连接成一个行字符串,则在进行解析的子组件部分中。
import { Component, OnInit, HostBinding, Input } from '@angular/core';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
@Component({
selector: 'app-button',
templateUrl: './button.component.html',
})
export class ButtonComponent implements OnInit {
@HostBinding('style') baseStyle: SafeStyle;
@Input()
set style(style: string | object) {
let mappedStyles = style as string;
if (typeof style === 'object') {
mappedStyles = Object.entries(style).reduce((styleString, [propName, propValue]) => {
propName = propName.replace(/([A-Z])/g, matches => `-${matches[0].toLowerCase()}`);
return `${styleString}${propName}:${propValue};`;
}, '');
this.baseStyle = this.sanitizer.bypassSecurityTrustStyle(mappedStyles);
} else if (typeof style === 'string') {
this.baseStyle = this.sanitizer.bypassSecurityTrustStyle(mappedStyles);
}
}
constructor(private sanitizer: DomSanitizer) {}
ngOnInit() {}
}
您可以在上面看到baseStyle 具有HostBinding 到style 的组件绑定。
当style 输入被传递时,setter 将触发,检查是否传递了字符串或对象,将其解析为字符串并清理该 css 并将其分配给baseStyle,因此主机样式将发生变化。
编辑:
正如@Scorpioo590 所说,这可以替换为[ngStyle]。
所以这似乎是不必要的。也许至少这可以显示您可以使用样式和 HostBinding 做什么。
【讨论】: