template reference variable is often a reference to a DOM element within a template. It can also refer to a directive (which contains a component), an element, TemplateRef, or a web component.

Use the hash symbol (#) to declare a reference variable. The following reference variable, #phone, declares a phone variable on an <input> element.

<input #phone placeholder="phone number" />

<!-- lots of other elements -->

<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button

We can refer to a template reference variable anywhere in the component’s template. Here, a <button> further down the template refers to the phone variable.

Angular assigns each template reference variable a value based on where we declare the variable:

  • If we declare the variable on a component, the variable refers to the component instance.
  • If we declare the variable on a standard HTML tag, the variable refers to the element.
  • If we declare the variable on an <ng-template> element, the variable refers to a TemplateRef instance, which represents the template.
  • If the variable specifies a name on the right-hand side, such as #var="ngModel", the variable refers to the directive or component on the element with a matching exportAs name

How a reference variable gets its value

In most cases, Angular sets the reference variable’s value to the element on which it is declared. In the previous example, phone refers to the phone number <input>. The button’s click handler passes the <input> value to the component’s callPhone() method.

The NgForm directive can change that behavior and set the value to something else. In the following example, the template reference variable, itemForm, appears three times separated by HTML.

<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
  <label for="name"
    >Name <input class="form-control" name="name" ngModel required />
  </label>
  <button type="submit">Submit</button>
</form>

<div [hidden]="!itemForm.form.valid">
  <p>{{ submitMessage }}</p>
</div>

The reference value of itemForm, without the ngForm attribute value, would be the HTMLFormElement. There is, however, a difference between a Component and a Directive in that a Component will be referenced without specifying the attribute value, and a Directive will not change the implicit reference (that is, the element).

However, with NgFormitemForm is a reference to the NgForm directive with the ability to track the value and validity of every control in the form.

The native <form> element doesn’t have a form property, but the NgForm directive does, which allows disabling the submit button if the itemForm.form.valid is invalid and passing the entire form control tree to the parent component’s onSubmit() method.

The scope of a reference variable is the entire template. So, don’t define the same variable name more than once in the same template as the runtime value will be unpredictable.

Well! We cannot access the template reference variable inside the component class or typescript logic but still, we can use that variable by passing it through a method which will be called by the event listener.

<div>
<label for="Name">Name</label>
<input type="text" #nameInput>
<button (click)="onSaveName(nameInput)">Save Name</button>
</div>

Passing that local variable with omitting # symbol.

import {
  Component,
} from '@angular/core';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor() {}
  onSaveName(name: HTMLInputElement) {
    console.log(( < HTMLInputElement > name).value);
  }
}

Here, we are expecting a name parameter which will be of type HTMLInputElement and also inside the body of the method, we have wrapped the name variable with the same type. It is because we are accessing the instance of the element which is <input> type.

insert

We can see in the above screenshot that all the generic properties of Input element are wrapped under HTMLInputElement. It is one of good practice to explicitly define the parameter type we are about to receive in the method to avoid further confusion with variable types in the method body. If we do so, Editor intellisense will show us all the methods and properties can be called on the received parameter property.

insert

@ViewChild()

There is one more way to accessing the template reference variable is using @ViewChild() decorator, using this decorator, we can reference that variable inside our component without passing it via method as a parameter, or we can say, if we need to access it before the onSaveName() method get executed.

import {
  Component,
  OnInit,
  ViewChild,
  ElementRef,
  AfterViewChecked
} from '@angular/core';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewChecked {
  @ViewChild('nameInput') inputNameRef: ElementRef;
  constructor() {}
  ngOnInit() {}
  onSaveName(name: HTMLInputElement) {
    console.log(( < HTMLInputElement > name).value);
    console.log(this.inputNameRef.nativeElement.value);
  }
  ngAfterViewChecked() {
    console.log("After view got Checked");
    console.log(this.inputNameRef.nativeElement.value);
  }
}

Here, the output will be logged 3 times on the control, two for the method and one after AfterViewChecked lifecycle hook. Don’t forget that with the @ViewChild() decorator, our reference to the variable will be ElementRef type Since we are trying to access a reference to an element of our template view. ElementRef has sub-property called nativeElement which wraps all the underlying properties of that specific referenced element.

Alternative syntax

We can use the ref- prefix alternative to #. This example declares the fax variable as ref-fax instead of #fax.

<input ref-fax placeholder="fax number" />
<button (click)="callFax(fax.value)">Fax</button>
Reference:

https://angular.io/

http://www.writesomecode.in/

By Shabazz

Software Engineer, MCSD, Web developer & Angular specialist

Leave a Reply

Your email address will not be published. Required fields are marked *