These two methods may seem different from the outside. However, when looking closely at reactive forms, the setup is quite similar. In app.module.ts, reactive forms are initialized as follows:
import { ReactiveFormsModule } from '@angular/forms';
imports: [BrowserModule, ReactiveFormsModule],
Then, in your parent.component.ts file:
import { FormGroup, FormControl, Validators } from '@angular/forms';
cardForm = new FormGroup({
name: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(5),
]),
});
cardForm
represents an instance of FormGroup. This form needs to be connected to the form itself.
<form [formGroup]="cardForm" (ngSubmit)="onSubmit()"></form>
This specifies that the form will be managed by "cardForm". Inside each input element of the form, a controller is added to listen for any changes and pass those changes to "cardForm".
<form [formGroup]="cardForm" (ngSubmit)="onSubmit()">
<app-input label="Name" [control]="cardForm.get('name')"> </app-input>
</form>
cardForm.get('name')= new FormControl('initValue', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(5),
]),
In essence, FormControl instances are placed within the input elements. They listen for all changes and report them to the FormGroup instance. The setup of FormGroup and FormControl is explicitly done in the class component.
On the other hand, when working with template forms, there is no need to set up anything in the parent.component.ts file. The code is written inside the parent.component.html file. Angular still creates a FormGroup and handles the form through it behind the scenes. In app.module.ts:
import { FormsModule } from '@angular/forms';
imports: [BrowserModule, FormsModule],
No code is written for the FormGroup and FormControl. The setup happens in the template file:
<form (ngSubmit)="onSubmit()" #emailForm="ngForm">
#emailForm creates a reference to the "FormGroup" that is created behind the scenes. This allows access to properties like "touched" and "valid". Input elements are then placed inside the form:
<input
type="email"
required
name="email"
[(ngModel)]="email"
#emailControl="ngModel"
/>
ngModel is a directive that instructs Angular to track the value in this input. It adds event handlers to the input element.
[(ngModel)] represents two-way binding, combining property binding and event handling syntax. If the value of "email" in the class changes, the input value is updated, and vice versa. The "email" property is defined in the class component.
export class AppComponent {
email: string; // [(ngModel)] communicates with this
onSubmit() {
console.log(this.email);
}
}
#emailControl serves as a reference to the input control. The name can be customized as needed.
emailControl===emailForm.controls.email
In the template form, #emailForm
represents the FormGroup, while #emailControl
represents the FormControl.
- In reactive forms, validation logic is explicitly set within the FormControl. In template forms, the inclusion of "required" in the
input
element automatically assigns it to Validator.required
.