angularangular18

Get directive of component from another component


I have the following template:

<sc-list #list drawer-track> </sc-list>

<sc-drawer [drawerTrack]="list"></sc-drawer>

I need to get the host element of sc-list inside sc-drawer component using the drawer-track directive.

I was trying to use Injector or EnvironmentInjector inside sc-drawer component, but I couldn't figure out how to use it, or maybe there is another approach that I don't know.


Solution

  • When you create a directive you can indicate "exportAs"

    @Directive(
    {
      selector: 'drawer-track',
      exportAs: 'drawerTrack'  //<--this line
    })export class DrawerTrackDirective {
    
    }
    

    Now, when use a template reference variable you can indicate that your variable should be this directive

    <sc-list #list="drawerTrack" drawer-track> </sc-list>
    

    (It the same, e.g. when you use ngModel and write #name="ngModel")

    Now, you can inject in your drawerTrack directive the elementRef (declare as public) or the sc-list (use Optional if your directive is applied not only to a sc-list)

    constructor(public elementRef:ElementRef,
                @Optional() public scList:ScListComponent){}
    

    So you can use in .ts in your sc-drawer

    console.log(this.drawerTrack.elementRef);
    console.log(this.drawerTrack.scList.any-property);
    //or execute a function
    this.drawerTrack.scList.any-function()
    

    NOTE: when we use ViewChild, we can use, {read:ClassName}, e.g.

    @ViewChild('list',{read:DrawerTrackDirective})
                       listAsTrackDirective!:DrawerTrackDirective
    

    And in .html

    <sc-drawer [drawerTrack]="listAsTrackDirective"></sc-drawer>