How to add/remove class from directive

后端 未结 4 694
误落风尘
误落风尘 2020-12-16 15:16

Using a custom directive how would you add/remove a class on the host element based on a specific conditions?

Example:



        
相关标签:
4条回答
  • 2020-12-16 15:37
    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);
       }
    
    }
    
    0 讨论(0)
  • 2020-12-16 15:49

    When you are using directives in Angular you would want to use @HostBinding, and bind to class.your-class in order to be able to add/remove your class based on a predicate. You don't need to DI in the Renderer2 to effectively add/remove classes.

    For example, when using Bootstrap and Reactive Forms and you want to indicate a valid or invalid form field you can do something like:

    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);
      }
    }
    

    This is not a rigorous example, but it illustrates the use of @HostBinding, and I created the example in a StackBlitz

    0 讨论(0)
  • 2020-12-16 15:57

    Directive example for opening and closing toggle on dropdown

    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;
    }
    }
    

    Component add directive 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>
    

    Make sure to Include new directive in the @NgModule declarations

    0 讨论(0)
  • 2020-12-16 16:01

    If you don't want to use the ngClass directive (Hint: you can pass a function to [ngClass]="myClasses()" if it would be to messy inline in your template) you can just utilize the Renderer2 for it to add one or more classes:

    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);
       }
    
    }
    
    0 讨论(0)
提交回复
热议问题