使用指令将类添加到宿主元素[重复]

Posted

技术标签:

【中文标题】使用指令将类添加到宿主元素[重复]【英文标题】:Using a directive to add class to host element [duplicate] 【发布时间】:2017-01-31 00:50:08 【问题描述】:

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

setElementClass(renderElement: any, className: string, isAdd: boolean) : void

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

【问题讨论】:

导入一个css类是什么意思? className 是字符串,为什么你必须加载或转换或导入 css 类? 【参考方案1】:

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

@Directive(
   selector: '[whatever]'
)
class WhateverDirective 
   constructor(renderer: Renderer, el: ElementRef) 
       renderer.setElementClass(el.nativeElement, 'whatever-css-class', true);
   

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

【讨论】:

是的,绝对是,到目前为止我理解了 setElementClass 函数,但是什么是 CSS 类,属性指令没有 css 文件,或者有可能添加一个吗?跨度> 对,所以你可以做的是在css文件中定义你在html中引用的类,这样它就会被应用到元素上。 Renderer 类现已弃用。请改用Renderer2。 您不需要 DI 渲染器,而是使用 @HostBinding('class.your-class') - ***.com/a/58071653/1148107【参考方案2】:

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

使用@HostBinding

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

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

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

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

  constructor() 
  

将@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');
  

使用渲染器

更底层的 API 是 Renderer2。 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');
  

【讨论】:

我用for循环的classes数组,实用吗? 对于多个类,您应该执行一个循环。如果您查看source,您会看到Angular 调用了classList.add 方法。虽然这个原生方法支持多个参数,但 Angular 实现一次只允许传递一个类名。 从构造函数推送类似乎不起作用。但它适用于 ngAfterViewInit setter 似乎永远不会被调用,导致主机的任何初始类丢失:-( 您不需要 DI 渲染器或操作现有类,而是使用 @HostBinding('class.your-class') - ***.com/a/58071653/1148107【参考方案3】:

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

例子:

import  HostBinding  from '@angular/core';

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

    @HostBinding('class')
    className = 'my-directive-css-class';

【讨论】:

如果你想添加一个基于其他属性的类,这很有用,即动态: 我认为这只对完全替换可能已经在 HTML 中定义的类有用。我将如何使用这种方法添加一个类?渲染器似乎更灵活。 这种语法更好:@HostBinding('class.isPlaying') class_isPlaying = true;(见***.com/a/35183074/16940)。它将切换类,而不是仅仅清除整个属性。 @Simon_Weaver 这种语法可能更好,如果您需要基于属性切换一个类,它仍然是一个不错的选择。然而,在最新版本的 Angular(例如 10)中,@HostBinding('class') 似乎并没有消除整个属性。它的行为就像模板中的 [class] 绑定,因为您可以将类作为空格分隔的字符串、字符串数组,甚至将条件类作为对象(但请注意,它不会检测到数组或对象)。参考:angular.io/guide/…【参考方案4】:

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

你让我知道你的想法

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;

【讨论】:

以上是关于使用指令将类添加到宿主元素[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在另一个指令的宿主中使用指令

如何在自定义组件宿主元素上使用自定义指令

仅当子容器具有内容时,如何将类添加到特定的父元素

如何使用 PHP 将类添加到“a href”元素?

Sass:之后是不是可以使用 Sass 将类添加到 HTML 元素?

将类添加到元素