【问题标题】:How to add/remove class from directive如何从指令中添加/删除类
【发布时间】:2017-05-22 02:24:41
【问题描述】:

使用自定义指令,您将如何根据特定条件在宿主元素上添加/删除类?

示例:

@Directive({
  selector: '[customDirective]'
})
export class CustomDirective {
  constructor(service: SomService) {
    // code to add class

    if (service.someCondition()) {
        // code to remove class
    }
  }
}

【问题讨论】:

标签: angular angular2-directives angular-directive


【解决方案1】:

如果您不想使用ngClass 指令(提示:如果您的模板中的内联混乱,您可以将函数传递给[ngClass]="myClasses()")您可以使用Renderer2 来实现添加一个或多个类:

export class CustomDirective {

   constructor(private renderer: Renderer2,
               private elementRef: ElementRef,
               service: SomService) {
   }

   addClass(className: string, element: any) {
       this.renderer.addClass(element, className);
       // or use the host element directly
       // this.renderer.addClass(this.elementRef.nativeElement, className);
   }

   removeClass(className: string, element: any) {
       this.renderer.removeClass(element, className);
   }

}

【讨论】:

  • 什么是宿主元素?
  • @Karty 指令附加到的元素
【解决方案2】:

当您在 Angular 中使用指令时,您可能希望使用 @HostBinding,并绑定到 class.your-class,以便能够基于谓词添加/删除您的类。您无需在 Renderer2 中进行 DI 即可有效地添加/删除类。

例如,当使用 Bootstrap 和 Reactive Forms 并且您想指示有效或无效的表单字段时,您可以执行以下操作:

import { Directive, Self, HostBinding, Input } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
  selector: '[appCheckFormFieldValidity]'
})
export class CheckFormFieldValidity{
  @Input() public class: string;

  constructor(
    @Self() private ngControl: NgControl
  ) { }

  @HostBinding('class.is-valid')
  public get isValid(): boolean {
    return this.valid;
  }

  @HostBinding('class.is-invalid')
  public get isInvalid(): boolean {
    return this.invalid;
  }

  public get valid(): boolean {
    return this.ngControl.valid && 
    (this.ngControl.dirty || this.ngControl.touched);
  }

  public get invalid(): boolean {
    return !this.ngControl.pending &&
      !this.ngControl.valid &&
      (this.ngControl.touched || this.ngControl.dirty);
  }
}

这不是一个严格的例子,但它说明了@HostBinding的使用,我在StackBlitz中创建了例子

【讨论】:

  • 很遗憾,此示例不适用于结构指令,并且必须手动添加类。
【解决方案3】:

在下拉菜单中打开和关闭切换的指令示例

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

@Directive({
    selector: '[appDropDown]',
})
export class DropsownDirective{

@HostBinding('class.open') isopen = false;
@HostListener('mouseenter') onMouseEnter(){
this.isopen = !this.isopen;
}
@HostListener('mouseleave') onMouseLeave(){
    this.isopen = !this.isopen;
}
}

组件添加指令 appDropDown

<div class="col-xs-12">
        <div class="btn-group" appDropDown>
        <button class="btn btn-primary dropdown-toggle">
            Manage Movie <span class="caret"></span>
        </button>
        <ul class="dropdown-menu">
            <li><a href="#">To watching List</a></li>
            <li><a href="#">Edit Movie</a></li>
            <li><a href="#">Delete Movie</a></li>
        </ul>
    </div>

确保在 @NgModule 声明

【讨论】:

    【解决方案4】:
    export class CustomDirective {
       classname:string = "magenta";
    
       constructor(private renderer: Renderer2,
                   private elementRef: ElementRef,
                   service: SomService) {
       }
    
       addClass(className: string, element: any) {
            // make sure you declare classname in your main style.css
            this.renderer.addClass(this.elementRef.nativeElement, className);
       }
    
       removeClass(className: string, element: any) {
           this.renderer.removeClass(this.elementRef.nativeElement,className);
       }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-06
      • 1970-01-01
      • 2016-06-19
      相关资源
      最近更新 更多