问题
Do you guys know how I can batch inject style declarations in a component using the @HostBinding decorator? What I am trying is:
@HostBinding('style')
get style(): CSSStyleDeclaration {
return {
background: 'red',
color: 'lime'
} as CSSStyleDeclaration;
}
In my understanding this should inject the background and color style to the component, but it does not...
I can control individual style declarations like this:
@HostBinding('style.background') private background = 'red';
but I would like to do it for all of them, please help :P
this is the full code:
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello world!</h2>
</div>
`,
})
export class App {
// This works
@HostBinding('style.color') private color = 'lime';
/* This does not work
@HostBinding('style')
get style(): CSSStyleDeclaration {
return {
background: 'red'
} as CSSStyleDeclaration;
}
*/
constructor() {}
}
and a working plunker: https://plnkr.co/edit/CVglAPAMIsdQjsqHU4Fb?p=preview
回答1:
You need to pass the same value you would add to an element like <div style="...">
and sanitize the styles
@HostBinding('style')
get myStyle(): SafeStyle {
return this.sanitizer.bypassSecurityTrustStyle('background: red; display: block;');
}
constructor(private sanitizer:DomSanitizer) {}
working demo
回答2:
Here is a solution that can cover if you want to pass multiple css styles as string or as object with cammelCase conventions:
Parent HTML
<app-button [style]="styleFromParent">Some button</app-button>
Parent component has styleFromParent
property and it has simulation if that property is changed at some point:
Parent Component 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);
}
}
Child HTML
<ng-content></ng-content>
Child Component TS
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() {}
}
Above you can see that baseStyle
has HostBinding
to style
component binding.
When style
input is passed setter will triger, check if string or object is passed, parse it to string and sanitize that css and assign it to baseStyle
thus host style will change.
来源:https://stackoverflow.com/questions/46150788/inject-style-declarations-using-hostbinding-in-angular