【问题标题】:How to dynamically set component host style Angular 8如何动态设置组件宿主样式Angular 8
【发布时间】:2019-12-06 20:21:29
【问题描述】:

我想从父级动态设置子宿主组件元素的样式。

有一个解决方案可以为每种样式单独执行:

@HostBinding('style.width') @Input() width = 'auto'

但是这样我需要为不同的样式制作多行。

Bellow 是一种通过主机绑定和输入组合来实现此目的的解决方案。

【问题讨论】:

    标签: angular typescript binding components


    【解决方案1】:

    ngStyle 是为此指定的。

    <app-button [ngStyle]="{ marginTop: '10px', marginLeft: '50px' }">Some button</app-button>
    

    当然,您可以将其外包给控制器,而不是像这样将其硬编码到模板中。

    https://angular.io/api/common/NgStyle

    PS:由于 style 已经存在于所有元素上,我不确定您的代码的行为

    【讨论】:

    • 是的,这是一个好点。如果您想过滤掉某些样式,也许使用自定义主机绑定是有意义的。至于 [styles] 属性的行为,它按预期工作。
    【解决方案2】:

    如果您想将多个 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 具有HostBindingstyle 的组件绑定。 当style 输入被传递时,setter 将触发,检查是否传递了字符串或对象,将其解析为字符串并清理该 css 并将其分配给baseStyle,因此主机样式将发生变化。

    编辑:

    正如@Scorpioo590 所说,这可以替换为[ngStyle]。 所以这似乎是不必要的。也许至少这可以显示您可以使用样式和 HostBinding 做什么。

    【讨论】:

    • 对我来说不是不需要的,因为我想根据组件输入从子级设置主机。有这个真棒!
    猜你喜欢
    • 2015-12-27
    • 2019-09-12
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 1970-01-01
    • 2016-10-30
    相关资源
    最近更新 更多