0
votes

How would I go about using NgClass inside of a custom attribute directive to change the main elements CSS class?

If I have something like this:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <div class="box" myDir [ngClass]="{'blue': blue, 'red': red}">   </div>
    </div>
  `,
});

And then, inside of that myDir directive, something like this:

import { Directive, HostListener, OnInit } from '@angular/core';

@Directive({
  selector: '[myDir]'
})

export class MyDirDirective {
  blue: boolean;
  red: boolean;

  constructor() { 
  }

  ngOnInit() {
  } 

  @HostListener('mouseenter', ['$event'])
  onMouseEnter(event) {
    event.preventDefault();
    event.stopPropagation();

    this.blue = true;
    this.red = false;

    console.log('mouseenter');
  }

  @HostListener('mouseleave', ['$event'])
  onMouseLeave(event) {
    event.preventDefault();
    event.stopPropagation();

    this.blue = true;
    this.red = false;

    console.log('mouseleave');
  }

Do I not have access to the scope in which blue and red reside in? If I create a toggle, I can update those values with a button, but it doesn't seem like I can do it from within the directive itself. Is this an accurate observation and should I be doing it this way or is there an alternative that I'm not seeing in the docs?

1

1 Answers

0
votes

Properties blue\red in your case reside in the scope of parent component my-app .

You may create an Output event inside your directive which can be subscribed in the parent component to change the value,

Something similar to below,

@Directive({
  selector: '[myDir]'
})
export class MyDirDirective {
  blue: boolean;
  red: boolean;

  @Output() myEvent = new EventEmitter();

  @HostListener('mouseenter', ['$event'])
  onMouseEnter(event) {
    event.preventDefault();
    event.stopPropagation();
    this.myEvent.next('blue');
  }

  @HostListener('mouseleave', ['$event'])
  onMouseLeave(event) {
    event.preventDefault();
    event.stopPropagation();
    this.myEvent.next('red');
  }
}

and subscribe to this event in parent component to update color to blue\red.

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>
  <div class="box" myDir (myEvent)="myEvent($event)"
        [ngClass]="{'blue': color === 'blue', 'red': color === 'red'}"> Hello World!!</div>
  `,
  styles:[`
  .blue{
    border: 1px solid blue;
  }
  .red{
     border: 1px solid red;
  }`]
})
export class AppComponent { 
  name = 'Angular';
  color = 'blue';

  myEvent(val){
    this.color = val;
  }
}

Check this Plunker!!

Hope this helps!!