Access template variables through directive in angular

I am currently working on a directive which simply manipulates the dom elements.

I wanted to access to template variables of the element which is the host of the directive, but I was unable to do that, because the result is always undefined.

directive:

@Directive({
    selector: '[sample-directive]'
})
export class SampleDirective implements AfterViewInit {
    @ViewChild('queryMe') queryMe: ElementRef;

    ngAfterViewInit(): void {
        console.log(this.queryMe);    
    }
}

sampleComponent.template.html:

<div #queryMe></div>

usage:

<sample-component [sample-directive]></sample-component>

Is it possible to use template variables like that?

Upvotes: 2

Views: 4479

Answers (2)

user4676340
user4676340

Reputation:

Send the template variables over to your directive : stackblitz

@Input('appQuery') appQuery: HTMLElement;
<div [appQuery]="queryMe">
  <div #queryMe></div>
</div>

EDIT

Second solution : provide custom attributes to your query-able elements. Since template variables are just references to HTML elements, you will get pretty much the same result (except for one more attribute in your tag).

Stackblitz

get element() { return this.el.nativeElement; }
ngAfterViewInit() {
  console.log(this.element.querySelector('[queryMe]'));
}
<div appQuery>
  <div queryMe></div>
</div>

Upvotes: 3

SiddAjmera
SiddAjmera

Reputation: 39482

Angular Directives don't have a template. That's what differentiates them from Angular Components which does have templates.

Since directives have no templates, you can't get things like ViewChild or ContentChild on them. Also for the same reason, you'll not have implementations to AfterContentInit, AfterContentChecked, AfterViewInit, and AfterViewChecked interfaces.

So if you only want the HTMLElement from your host's template, give the div a class and access it from the directive using this:

import { ElementRef, Directive } from '@angular/core'

@Directive({
    selector: '[sample-directive]'
})
export class SampleDirective {

    constructor(private el: ElementRef) {}

    ngOnInit() {
      let elYoureLookingFor = this.el.nativeElement.querySelector('.class-on-div');
    }

}

Then, in your sampleComponent.template.html:

<div class="class-on-div"></div>

Upvotes: 2

Related Questions