0

I have defined a custom attribute directive:

import { Directive, ElementRef } from '@angular/core';
@Directive({
  selector: '.vvdirective'
})
export class VVdirectiveDirective {

  constructor(private elRef: ElementRef) {}
  ngOnInit() {
        this.elRef.nativeElement.style.backgroundColor = "gray";
        this.elRef.nativeElement.style.color = "navy";
        console.log("vv directive works!!")
  }
}

It changes the elements sharing the 'vvdirective' CSS class with a gray background and a navy font color. It also prints a console message.

It works for a traditional use case:

<div class="vvdirective">My custom attribute directive works in a plain old fashion way !</div>

Picture: enter image description here

BUT

When I want to use this directive inside a component:

HTML:

<div [ngClass]="klass" >My custom attribute directive works even embedded in a component</div>

& TS:

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-vvdiv',
  templateUrl: './vvdiv.component.html',
  styleUrls: ['./vvdiv.component.scss']
})
export class VvdivComponent implements OnInit {

  @Input() klass: string;

  constructor() { }

  ngOnInit() {
 }

}

& call in APP TS:

<app-vvdiv klass="vvdirective"></app-vvdiv>

It does not work (the background/font color do not change and no console message is printed):

Picture: enter image description here

It should be like that:

Picture: enter image description here

AND WHAT SURPRISED ME, is that in the end both of the code samples (the one with old fashion directive call, and the one with the call through a component) have the CSS class:

enter image description here

But only the first (not embedded in a component) is impacted by the directive changes.

It looks like the ngClass directive used in the component in the latter case, works differently.

Maybe it is related to the life cycle of the app, I don't know.

So if you have any idea how to make the component using both ngClass and my custom directive together, I will pay close attention to your answer!

HERE THE PLUNKER: plunker

HERE THE GITHUB REPOSITORY: git repo

Best,

vvauban
  • 165
  • 4
  • 8
  • Some similar topic: https://stackoverflow.com/questions/43981841/apply-attribute-directive-on-component-in-angular-4 – vvauban May 16 '20 at 08:45
  • as you describe it looks similar to these feature discussion, but in scanty way https://github.com/angular/angular/issues/8785 and not planed yet to implement – Radik May 16 '20 at 15:15
  • Another link I used: https://stackoverflow.com/questions/46302684/pass-parameter-to-angular-4-directive-on-input – vvauban May 16 '20 at 15:27

2 Answers2

0

Try this

<app-vvdiv (klass)="vvdirective"></app-vvdiv>
Sameera Herath
  • 173
  • 1
  • 12
  • It does not change. (No styling impacts, neither console log). – vvauban May 16 '20 at 09:11
  • Putting parenthesis is to bind an event handler to an @Output() or DOM event `(event)="expr"` ― What I did is bind a value to the property `prop="value"` ― Maybe it does not work because **properties** are **not visible in the DOM**. – vvauban May 16 '20 at 09:52
0

I changed the way to do by using a directive with an input.

TS of directive:

//The directive
import { Directive, ElementRef, Input, Renderer2 } from '@angular/core';

@Directive({
  selector: '[vvdirective]'
})
export class VVdirectiveDirective {
  @Input('vvdirective') params: string;
  constructor(
    private elRef: ElementRef,
    private renderer: Renderer2) { }
  ngOnInit() {
    if (this.params === 'vvstyle number two') {
      console.log("in the first condition for other style number two")
      console.log(this.params)
      this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'black');
      this.renderer.setStyle(this.elRef.nativeElement, 'color', 'yellow');
    } else {
      console.log("in the default condition for default style")
      console.log(this.params)
      this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'gray');
      this.renderer.setStyle(this.elRef.nativeElement, 'color', 'navy');
    }
  }
}

HTML of embedded component:

//the call to that directive in the embedded component
<div [vvdirective]="klass">My custom attribute directive works even embedded in a component</div>

HTML of app component:

//the call to that directive in the app component
<div  vvdirective="vvstyle">My custom attribute directive works in a plain old fashion way !</div>
<app-vvdiv klass="vvstyle"></app-vvdiv>
<app-vvdiv klass="vvstyle number two"></app-vvdiv>

That way I succeed to change the style of the component (without ngClass) and I am also able to trigger conditional statements (business rules).







Attachments

Updated git repo: https://github.com/vinny59200/VVAttributeDirectiveAndNgclass

Related plunker: https://plnkr.co/edit/UMuoS0lfxD7OuAsi?preview

Webpage screenshot:
enter image description here

Source screenshot:
enter image description here

vvauban
  • 165
  • 4
  • 8