Search code examples
javascriptangularchildren

Angular: there is a way to interact with second-level child component from a directive?


In HTML template, I have the following implementation:

<tr sliding>
  <td>Field 1</td>
  <td>Field 2</td>
  <td>
    <app-sliding>Field 3</app-sliding>
  </td>
</tr>

I have the following directive:

@Directive({
  selector: '[sliding]'
})
export class SlidingDirective {

  @HostListener('mouseenter', ['$event'])
  public onHover(e: Event): void {
    const el = e.target as HTMLElement;
    const appSliding = el.querySelector('app-sliding') as AppSlidingComponent;

    if (cdSliding) {
      appSliding.show();
    }
  }
}

And the following component:

@Component({
  selector: 'app-sliding',
  template: `
    <ng-content></ng-content>
  `
})
export class AppSlidingComponent {
  show() {
    console.log('yes');
  }
}

I would like that when the mouse overs <tr> DOM element, the directive call the method show() of AppSlidingComponent.

I tried to use @ViewChild implementation but I not able to see a second level child.

querySelector find the DOM element but considered as HTMLElement, not AppSlidingComponent.

There is a way to interact with the child component from the directive ?


Solution

  • Use ContentChild inside directive to get projected component instance.

    @ContentChild
    (SlidingComponent, {static:false}) compInst:SlidingComponent;
    
    @HostListener('mouseenter', ['$event'])
      public onHover(e: Event): void {
        const el = e.target as HTMLElement;
        const appSliding = el.querySelector('app-sliding');
        this.compInst.show();
      }
    
      constructor() { }
    
    }
    

    Example