使用指令将类添加到host元素

Dan*_*rez 27 angular2-directives angular

我目前正在学习Angular 2.我了解如何使用Angular Renderer设置一个ElementStyle,但现在我想使用该Renderer方法:

setElementClass(renderElement: any, className: string, isAdd: boolean) : void
Run Code Online (Sandbox Code Playgroud)

我的问题是如何将CSS类导入到我的属性指令中?我必须将我的CSS类转换为JSON吗?

cga*_*ian 60

原OP询问如何使用渲染器.为了完整性,我已经包含了@HostBinding.

使用@HostBinding

要向元素添加类,可以使用@HostBinding

import { Directive, HostBinding} from '@angular/core';

@Directive({
  selector: '[myDirective]',
})
export class MyDirective {

  @HostBinding('class')
  elementClass = 'custom-theme';

  constructor() {
  }
}
Run Code Online (Sandbox Code Playgroud)

将@HostBinding与多个类一起使用

为了使多个类更易于使用,您可以使用ES6 getter并在返回之前将它们连接在一起:

import { Directive, HostBinding} from '@angular/core';

@Directive({
  selector: '[myDirective]',
})
export class MyDirective {
  protected _elementClass: string[] = [];

  @Input('class')
  @HostBinding('class')
  get elementClass(): string {
      return this._elementClass.join(' ');
  }
  set(val: string) {
      this._elementClass = val.split(' ');
  }

  constructor() {
      this._elementClass.push('custom-theme');
      this._elementClass.push('another-class');
  }
}
Run Code Online (Sandbox Code Playgroud)

使用渲染器

更低级别的API是Render2.当您想要将一组动态类应用于元素时,Renderer2非常有用.

例:

import { Directive, ElementRef, Renderer2 } from '@angular/core';

@Directive({
  selector: '[myDirective]',
})
export class MyDirective {

  constructor(private renderer: Renderer2, hostElement: ElementRef) {
    renderer.addClass(hostElement.nativeElement, 'custom-theme');
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

为什么要使用Renderer或Renderer2类?在指令中执行此操作的首选方法是使用@HostBinding装饰器.

例:

import { HostBinding } from '@angular/core';

@Directive({
    selector: '[myDirective]'
})
export class MyDirective {

    @HostBinding('class')
    className = 'my-directive-css-class';
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这仅对完全替换可能已在HTML中定义的类有用.我如何用这种方法添加*类?渲染器似乎更灵活. (5认同)
  • 这种语法更好:`@HostBinding('class.isPlaying')class_isPlaying = true;`(请参阅此/sf/answers/2462815211/)。它将切换类,而不是仅仅擦除整个属性。 (3认同)
  • @Simon_Weaver 这种语法可能*更好*,并且如果您需要根据属性切换一个类,那么仍然是一个不错的选择。然而,在 Angular 的最新版本(例如 10)中,“@HostBinding('class')”似乎并没有消除整个属性。它的行为就像模板中的 [class] 绑定一样,因为您可以将类作为空格分隔的字符串、字符串数组,甚至条件类作为对象(但请注意,它不会检测对象内的更改)数组或对象)。参考: https : //angular.io/guide/attribute-binding#binding-to-the-class-attribute (3认同)

小智 6

只是另一种方法,但对我来说更容易理解。

你让我知道你的想法

import { Directive, Input} from '@angular/core';

@Directive({
  selector: '[whatever]',
  host: {
    // These are like ngClass class condition values
    '[class.custom-class1]': 'true', // Default class for example
    '[class.custom-class2]': 'foo === "expectedValue"', // Predicate1
    '[class.custom-class3]': 'foo !== "expectedValue"', // Predicate2
  },
})
export class WhateverDirective {
  @Input() foo: string;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

如何使用Renderer和ElementRef将css类添加到元素的示例.

@Directive({
   selector: '[whatever]'
})
class WhateverDirective {
   constructor(renderer: Renderer, el: ElementRef) {
       renderer.setElementClass(el.nativeElement, 'whatever-css-class', true);
   }
}
Run Code Online (Sandbox Code Playgroud)

whatever-css-class在css文件中定义,在html中引用