behind the scene they are same. In reactive form, this is what u import in app.module.ts:
import { ReactiveFormsModule } from '@angular/forms';
imports: [BrowserModule, ReactiveFormsModule],
then in your parent.component.ts
import { FormGroup, FormControl, Validators } from '@angular/forms';
cardForm = new FormGroup({
name: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(5),
]),
});
cardForm is an instance of FormGroup. We need to connect it to the form itself.
<form [formGroup]="cardForm" (ngSubmit)="onSubmit()"></form>
This tells that this form will be handled by "cardForm". inside each input element of the form, we will add controller to listen for all the changes and pass those changes to the "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 a nutshell, FormControl instances are placed in the input elements, they listen for all change and report them to FormGroup instance. We are setting up FormGroup and FormControl in the class component explciitly.
if you work with template forms, you do not set up anything in the parent.component.ts. you write your code inside the parent.component.html. BUT at this moment, angular behind the scene will still create FormGroup and will handle the form through FormGroup. in app.module.ts
import { FormsModule } from '@angular/forms';
imports: [BrowserModule, FormsModule],
we are not writing any code for the FormGroup and FormControl. we go to the template file:
<form (ngSubmit)="onSubmit()" #emailForm="ngForm">
#emailForm creates a ref to the "FormGroup" that created behind the scene. with this we can access to all of the properties of FormGroup like "touched", "valid" etc.
then we place input element inside the form:
<input
type="email"
required
name="email"
[(ngModel)]="email"
#emailControl="ngModel"
/>
ngModel is directive. tells Angular, we want to keep track of the value in this input. It will attach alot of event handler to the input element.
[(ngModel)] is two way binding. property binding and event handling syntax put together. if the value "email" in the class changes, update the input value, likewise if the input value changes, update the "email" in the class. we already defined "email" in the class component
export class AppComponent {
email: string; // [(ngModel)] communicates with this
onSubmit() {
console.log(this.email);
}
}
#emailControl is the reference to the input control. name could be anything.
emailControl===emailForm.controls.email
So in this template form, #emailForm represents the FormGroup, #emailControl represents the FormControl.
- in reactive forms, we write our validation logic inside the FormControl explicitly. But with template, if you check the
input element we added "required". when angular sees this, it will automatically assign it to Validator.required