A text box lets a user enter a value through an HTML input element. In the DOM, that element is represented by an HTMLInputElement; its value property holds the current contents. The input element is a void element, so it has no separate closing tag. section 13.2.1 section 3.2.1
To respond as the user types, bind the input event. The browser supplies an event through Angular’s $event variable, and the event target identifies the input element. A template expression can read its value with $any($event).target.value, but $any disables type checking for that expression: Angular otherwise sees the target through the general Event type, which does not expose an input-specific value property. section 13.2.1
Handle input without $any
Use (input)="handleInputEvent($event)" in the template. In the component, receive an Event, check ev.target instanceof HTMLInputElement, then read ev.target.value to update a signal. This produces the same update without disabling type checking. section 13.2.2
A template reference variable offers another way to reach the element: <input #product ... /> makes product refer to its HTMLInputElement, so bindings can read product.value or assign to it. This is useful for a local interaction, but relying on the element as the source of displayed state has a catch: user edits do not refresh other bindings unless an event binding runs. An (input)="false" binding can trigger that refresh, though component-backed data bindings avoid this awkward pattern. section 13.2.3
Listing 13.9. Using a template variable in the template.html file in the src/app folder
<div class="p-2">
<div class="bg-info text-white p-2">
Selected Product: {{product.value || '(None)'}}
</div>
<table class="table table-sm table-bordered">
<tr *ngFor="let item of products(); let i = index"
[class.bg-info]="product.value == item.name">
<td (mouseover)="product.value = item.name ?? ''">
{{i + 1}}
</td>
<td>{{item.name}}</td>
<td>{{item.category}}</td>
<td>{{item.price}}</td>
</tr>
</table>
<div class="form-group">
<label>Product Name</label>
<input #product class="form-control" (input)="false" />
</div>
</div>
See how one reference variable connects a text box to a displayed value and a table interaction, including the input binding needed to refresh the display. section 13.2.3
For an editable form, [(ngModel)] can instead bind each text box to a component property in both directions. Name, category, and price inputs update a Product object as the user edits them; an interpolated JSON representation shows the changes, and a Create button passes the object to a component method. Labels identify the fields, while Bootstrap classes provide their layout and styling. section 13.4.1
Listing 13.14. Replacing the contents of the template.html file in the src/app folder
<div class="p-2">
<div class="bg-info text-white mb-2 p-2">
Model Data: {{jsonProduct}}
</div>
<div class="form-group">
<label>Name</label>
<input class="form-control" [(ngModel)]="newProduct.name" />
</div>
<div class="form-group">
<label>Category</label>
<input class="form-control" [(ngModel)]="newProduct.category" />
</div>
<div class="form-group">
<label>Price</label>
<input class="form-control" [(ngModel)]="newProduct.price" />
</div>
<button class="btn btn-primary mt-2" (click)="addProduct(newProduct)">
Create
</button>
</div>
See the complete form template with three ngModel-bound inputs, live model display, and a Create button. section 13.4.1






