2

I have the following directive. I am trying to pass the class name that needs to be toggled when the link/button is clicked. I keep getting undefined in debug console. HostListener takes array of args - i guess i am not sure how to pass them and cant seem to find example of it.

   @Directive({
  selector: '[appSidebarToggler]'
})
export class SidebarToggleDirective {

  constructor(public elementRef: ElementRef) {
  }

  @HostListener('click', ['$event', '$tobeToggledClassName'])

  toggleOpen($event: any, $tobeToggledClassName: any) {
    $event.preventDefault();
    console.log("class to be toggled is - >" + $tobeToggledClassName);
    console.log("ref - >" + this.elementRef);
    document.querySelector(tobeToggledClassName).classList.toggle('sidebar-hidden');

  }
}

and i am using it like this in my component :

<a class="" href="#" sidebarToggler tobeToggledClassName="sideMenu">&#9776;</a>

thanks.

2 Answers 2

4

You could pass class name inside Input binding of directive. You can easily retrieve a value of binding at any instance.

@Directive({
  selector: '[appSidebarToggler]'
})
export class SidebarToggleDirective {
  @Input() tobeToggledClassName: string;
  constructor(public elementRef: ElementRef) {
  }

  @HostListener('click', ['$event'])

  toggleOpen($event: any) {
    $event.preventDefault();
    console.log("class to be toggled is - >" + this.tobeToggledClassName);
    console.log("ref - >" + this.elementRef);
    document.querySelector(this.tobeToggledClassName).classList.toggle('sidebar-hidden');

  }
}

Html

<a class="" href="#" sidebarToggler tobeToggledClassName="sideMenu">&#9776;</a>
OR
<a class="" href="#" sidebarToggler [tobeToggledClassName]="'sideMenu'">&#9776;</a>
Sign up to request clarification or add additional context in comments.

Comments

2

You can pass it like:

@HostListener('click', ['$event', '$event.target.getAttribute("tobeToggledClassName")'])

Example 1

or use injected ElementRef

this.elementRef.nativeElement.getAttribute("tobeToggledClassName")

Example 2

or inject @Attribute in contstructor of your directive:

constructor(...@Attribute('tobeToggledClassName') private tobeToggledClassName: string) {}

Example 3

4 Comments

+ 1 I personally like 1st one, all three are nicer way. Question What will happen incase I want to pass some dynamic value to HostListner function.?
@PankajParkar I don't argue :) I just was looking for something else than standart Input :) I upvoted you too
@PankajParka For dynamic value we can use [attr.name] plnkr.co/edit/umXy6QMtO4dspRO1BRgo?p=preview So we don't relay on @Input property and we have minus one line in our class )
No, I don't meat in that way. I'm curious to know, I'm 100% sure you must know better way

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.