Skip to main content

Reactive Forms

Reactive Forms נותנים לנו אפשרות שליטה גדולה יותר וגמישות בבניית טפסים. מבנה הטופס מוגדר בתוך קובץ ה-ts.

  1. מגדירים את הטופס בתוך קובץ ה-ts.
  2. מוסיפים ולידציות.
  3. מחברים את הגדרת הטופס לטופס ב-html.

כדי להשתמש ב-reactive forms צריך לייבא אותם ל-app module.

app.module.ts
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

הגדרת טופס Reactive Form

גם לקומפוננטה צריכים לייבא את רכיבי הטפסים.

formComponent.ts
import { FormGroup, FormControl } from '@angular/forms';

loginReactiveForm: FormGroup = new FormGroup({
user: new FormControl(''),
password: new FormControl(''),
});

אפשר גם לתת ערך ברירת מחדל לשדה בטופס.

formComponent.ts
category: new FormControl('Papers');

אחרי שמגדירים את הטופס צריך לחבר אותו לטופס בקובץ ה-html. נשתמש ב-ngSubmit כדי להגדיר את הפונקציה שתופעל בזמן שליחת הטופס.

formComponent.html
<div class="container">
<h1 class="mb-4">Reactive forms</h1>
<form [formGroup]="loginReactiveForm" (ngSubmit)="loginUser()">
<input type="text" formControlName="user" placeholder="Enter name"/>
<br /><br />
<input type="password" formControlName="password" placeholder="Enter password"/>
<br /><br />
<button>Login</button>
</form>
</div>

את הפונקציה נפעיל מתוך ה-class.

formComponent.ts
loginUser() {
console.log(this.loginReactiveForm.value);
}

Form validation

כדי להשתמש בולידציות צריך לייבא אותן.

formComponent.ts
import { FormGroup, FormControl, Validators } from '@angular/forms';

loginReactiveForm = new FormGroup({
user: new FormControl('', [Validators.required]),
password: new FormControl('', [
Validators.required,
Validators.minLength(6),
]),
});

אפשר להשתמש בולידטורים שונים כמו: required, min, max, email, minLength, maxLength.

אם שדה לא עבר את הולידציה, נרצה לשנות את העיצוב שלו כך שהשגיאה תבלוט למשתמש.

formComponent.css
input.ng-invalid.ng-touched{

}

כדי להראות את השגיאות נשתמש בפונקציית get לקבל את השדה של הטופס:

formComponent.ts
get user() {
return this.loginReactiveForm.get('user');
}
get password() {
return this.loginReactiveForm.get('password');
}

עכשיו אפשר להראות את השגיאות בטופס ה-html.

formComponent.html
<form [formGroup]="loginReactiveForm" (ngSubmit)="loginUser()">
<input type="text" formControlName="user" placeholder="Enter name" />
<br /><br />

<div
class="alert alert-danger"
role="alert"
*ngIf="user && user.invalid && user.touched">
The user name is not valid.
</div>

<br />

<input
type="password"
formControlName="password"
placeholder="Enter password"/>

<br /><br />

<div
class="alert alert-danger"
role="alert"
*ngIf="password && password.invalid && password.touched">
The password is not valid.
</div>

<br />
<button [disabled]="loginReactiveForm.invalid">Login</button>
</form>

Form group

אפשר לקבץ כמה שדות אחת קבוצה אחת. מגדירים container לקבוצה ושמים בתוכו את השדות הרצויים.

comp.html
<form [formGroup]="contactForm" (ngSubmit)="onContactSubmit()">
<div formGroupName="presonalDetails">
<input type="text" formControlName="firstName">
<input type="text" formControlName="lastName">
<input type="text" formControlName="email">
<span *ngIf="!contactForm.get('presonalDetails.email')">Enter a valid email.</span>
</div>

<input type="text" formControlName="message">
</form>

מבנה של טופס פשוט:

comp.ts
contactForm: FormGroup = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl(''),
message: new FormControl(''),
});

מבנה של טופס עם קבוצה.

comp.ts
contactForm: FormGroup = new FormGroup({
presonalDetails: new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl(''),
}),

message: new FormControl(''),
});

Form array

אפשר להוסיף מערכים לטופס באנגולר על ידי FormArray. נגדיר את subjects כמערך וכל פעם כשנוסף נושא בטופס נכניס אותו לתוך המערך.

comp.ts
contactForm: FormGroup = new FormGroup({
presonalDetails: new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl(''),
}),
message: new FormControl(''),
subjects: new FormArray([
new FormControl(null),
])
});

addSubject(){
(<FormArray>this.contactForm.get('subjects')).push(new FormControl(null));
}
comp.html
<form [formGroup]="contactForm" (ngSubmit)="onContactSubmit()">
<div formGroupName="presonalDetails">
<input type="text" formControlName="firstName" />
<input type="text" formControlName="lastName" />
<input type="text" formControlName="email" />
<span *ngIf="!contactForm.get('presonalDetails.email')"
>Enter a valid email.</span
>
</div>
<input type="text" formControlName="message" />
<div formArrayName="subjects">
<ng-container
*ngFor="let subject of contactForm.get('subjects')['controls']; index as i"
>
<input type="text" placeholder="add subject..." formControlName="{{ i }}"/>
</ng-container>
<button (click)="addSubject()">Add subject</button>
</div>
</form>

אפשר ליצור ולידציות גם למערך.

comp.ts
(<FormArray>this.contactForm.get('subjects')).push(new FormControl(null, Validators.required));