embert
embert

Reputation: 7592

Tagging a form field #myFormField vs #myFormField="ngModel"

Could somebody point out please:

What exactly happens/changes when a #myFormField is extended to #myFormField="ngModel"? And what is the name of these notations?

import { Component, ViewChild } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  @ViewChild('inputPhoneNumber') viewChildPhoneNumber: number;
  phoneNumber: number;
}

Case 1: #inputPhoneNumber with output below

<p> Input Field</p>

<input 
class="form-control" 
type="text" 
[(ngModel)]="phoneNumber"
pattern="[\d]*" 
#inputPhoneNumber
required
/>
<div *ngIf="inputPhoneNumber.errors?.pattern"> 
  <b>Phone number must only contain digits</b>
</div>

<div>Two Way Binding: <b>{{phoneNumber}}</b></div>
<div>ViewChild: <b>{{viewChildPhoneNumber.nativeElement.value}}</b></div>
<div>#inputPhoneNumber: <b>{{inputPhoneNumber.value}}</b></div>

Case 1 Output (<code>#inputPhoneNumber</code>)

Case 2 Output - Extending same code to #inputPhoneNumber="ngModel" Case 2 Output

StackBlitz

Upvotes: 0

Views: 62

Answers (1)

SiddAjmera
SiddAjmera

Reputation: 39432

Just supplying an input tag with a template variable, #inputPhoneNumber will assign the JavaScript Object Representation of that HTMLElement to the template variable.

Try it with this:

<p> Input Field - With Just Template Varaible:</p>

<input 
  class="form-control" 
  type="text" 
  [(ngModel)]="phoneNumber"
  pattern="[\d]*" 
  #first
  required
  />

<div *ngIf="first.errors?.pattern"> 
  Phone number must only contain digits
</div>

<div>Two Way Binding: {{phoneNumber}}</div>
<div>ViewChild Native Element: {{viewChildFirst?.nativeElement | json}}</div>
<div>ViewChild Control: {{viewChildFirst.control | json}}</div>
<div>#first: {{first?.value}}</div>

And in the Component Class:

@ViewChild('first') viewChildFirst;

As it is quite apparent, viewChildFirst.control will not be defined in this case.


But assigning ngModel to the template variable will assign the FormControl representation of that HTML Element to the template variable.

Try it with this:

<p> Input Field - With Template And ngModel assigned</p>

<input 
  class="form-control" 
  type="text" 
  [(ngModel)]="phoneNumber"
  pattern="[\d]*" 
  #second="ngModel"
  required
  />

<div *ngIf="second.errors?.pattern"> 
  Phone number must only contain digits
</div>

<div>Two Way Binding: {{phoneNumber}}</div>
<div>ViewChild Native Element: {{viewChildSecond?.nativeElement}}</div>
<div>ViewChild Conttrol: {{viewChildSecond.control | json}}</div>
<div>#second: {{second?.value}}</div>

<hr>

And in the Component Class:

@ViewChild('second') viewChildSecond;

This time around, viewChildSecond?.nativeElement would not be defined but viewChildSecond.control would be.


You can check it out by exactly printing out the template variable as I've done above. Here's a Working Sample StackBlitz for your ref.

Upvotes: 1

Related Questions