Angular 6.0.0中如何通过指令动态追加CSS类而非覆盖原有类
解决Angular指令动态追加CSS类不覆盖原有类的问题
嘿,这个问题我之前在项目里也遇到过!直接用@HostBinding('class')确实会把元素上原有的类给清空,完全不是我们想要的追加效果。给你几个实用的解决方案,按需选就行:
方案一:用Renderer2操作类列表(最推荐)
Renderer2是Angular官方推崇的DOM操作方式,它的addClass和removeClass方法会安全地修改类列表,完全不会影响元素上已有的类,还能处理变量变化时的类更新(移除旧类、添加新类)。
修改你的指令代码如下:
import { Directive, Input, Renderer2, ElementRef, OnChanges, SimpleChanges } from '@angular/core'; @Directive({ selector: '[appendBusinessLogicClass]' }) export class AppendBusinessLogicClassDirective implements OnChanges { readonly prefix = 'prefix'; private previousDynamicClass: string | null = null; constructor( private renderer: Renderer2, private el: ElementRef ) {} @Input('appendBusinessLogicClass') targetVariable!: string; ngOnChanges(changes: SimpleChanges): void { // 先移除上一次添加的动态类(避免类堆积) if (this.previousDynamicClass) { this.renderer.removeClass(this.el.nativeElement, this.previousDynamicClass); } // 生成新的动态类并添加 const newDynamicClass = `${this.prefix}-${this.targetVariable}`; this.renderer.addClass(this.el.nativeElement, newDynamicClass); this.previousDynamicClass = newDynamicClass; } }
使用的时候,原有class="class1"会被完整保留,指令只会追加动态生成的类:
<div class="class1" [appendBusinessLogicClass]="variable"></div>
方案二:结合@HostBinding与原有类合并
如果你更倾向用@HostBinding实现,可以通过ElementRef获取元素初始的类列表,在setter里把原有类和动态类合并后再绑定:
import { Directive, Input, HostBinding, ElementRef } from '@angular/core'; @Directive({ selector: '[appendBusinessLogicClass]' }) export class AppendBusinessLogicClassDirective { readonly prefix = 'prefix'; // 保存元素初始的类集合 private originalClasses = this.el.nativeElement.className; constructor(private el: ElementRef) {} @HostBinding('class') combinedClasses!: string; @Input('appendBusinessLogicClass') set appendBusinessLogicClass(variable: string) { // 合并原有类和动态生成的类 this.combinedClasses = `${this.originalClasses} ${this.prefix}-${variable}`; } }
这个方案的缺点是:如果元素的原有类在组件生命周期中被其他代码动态修改,这里保存的originalClasses不会同步更新。如果你的元素类是固定不变的,这个方案足够简洁。
内容的提问来源于stack exchange,提问作者Mike Kovetsky
相关产品推荐
相关产品推荐

