2

I have a problem with attribute directive. I've followed the tutorial.

Directive is generated using CLI, so I've used ng g directive <directivename>, and is purposely put in the top level, altogether with app.module.ts.

My app.module.ts looks like this (and I must have omitted all the imports due to proprietary names of the modules):

// Directives
import { EventhoverDirective } from './eventhover.directive';

@NgModule({
  declarations: [
    // all the relevant component inputs are here
    EventhoverDirective
  ],
  imports: [
   // modules are here
  ],
  providers: [
    // providers are here
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Directive itself looks like:

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

@Directive({
  selector: '[appEventhover]'
})
export class EventhoverDirective implements OnInit {

  constructor(private el: ElementRef, private renderer: Renderer2) { }

  ngOnInit() {
    console.log('Directive called');
  }

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight('blue');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  highlight(color: string) {
    this.renderer.setStyle(this.el.nativeElement, 'color', color);
  }

}

And I use it inside the HTML like this:

<div class="container top-spacer">
  <div class="row text-center" >
    <div appEventhover class="col event" *ngFor="let event of eventList" (click)="storeEvent(event.job)">
      <img class="img-responsive" src="{{backendRoute}}/{{event.track_image_off}}">
      <p > {{event.name}} </p>
    </div>
  </div>
</div>

However, it's not working. It doesn't even spit out any error, nor anything else. What I might be doing wrong?

Thank you in advance for your help.

mutantkeyboard
  • 1,614
  • 1
  • 16
  • 44

2 Answers2

5

Just to add to the already provided answers and to share what I learnt from experience. The directive and component where it is to be used have to be included in the same module. See description below.

Assuming you have two modules A and B with components Ac and Bc respectively then a directive D. To use D in Ac, both D and Ac have to be included to module A that is to say wherever Ac is included D has to be included as well.

And as for Bc, because D is already included to module A it cannot be included to module B again else you get multiple declaration error yet D will still not take effect on Bc at this point.

Solution to Bc would imply moving D, Ac and Bc to a shared module where these three can be included in one place.

By inclusion I mean something similar to the example below. Also note that this solution is based on Angular 5

@NgModule({
    imports: [
       ***
    ],
    declarations: [**your directive and component**],
    providers: [***],
})
oguz ismail
  • 1
  • 16
  • 47
  • 69
Marcel
  • 81
  • 1
  • 4
  • Thank you for the explanation. I had my directive in `Shared` module, but was trying to use it on a different Module `M`. Thing is, `Shared` module is already imported into `M` so I figured that would be enough. I had to include my directive in module `M` declarations as well before it could work. Now it's declared in both `M` and `Shared` modules but seems to work ok. – LocustHorde May 05 '23 at 13:53
2

Your directive code works. Here it is in a stackblitz. The directive itself is identical. I applied it to a simple <p> element and to a <div> using *ngFor.

I would guess that the issue you have is therefore somewhere else in your code.

rmcsharry
  • 5,363
  • 6
  • 65
  • 108