使用指令将类添加到宿主元素[重复]
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;
【讨论】:
以上是关于使用指令将类添加到宿主元素[重复]的主要内容,如果未能解决你的问题,请参考以下文章