Angular 7 – Reactive Forms

Merhaba,

Bu içeriğimizde, bir form üzerinde yapılan tüm aktiviteleri dinamik bir şekilde kontrol etmemizi sağlayan ve Angular 7 ile gelen Reactive Forms yapıları üzerine konuşuyor olacağız.

Reactive Forms; form üzerinde tüm input kontrolleriyle birlikte, kullanıcı ile etkileşime girecek ve bilgi alacak olan diğer nesneleri dinleyen, bu nesneler üzerinde anlık değişiklikleri takip edip bizlere ileten bir form çeşididir. Aynı zamanda etkin bir şekilde forma dair olan tüm validasyonları işleyen ve verilsel olarak önceden tanımlanmış değerlerle elimizdeki kontroller arasında yapılmış olan data binding sayesinde yapılan tüm çalışmaların tarafımızca rahat bir şekilde takip edilebilmesini sağlayan bir yapıya sahiptir.

Aslında bizler bu Reactive Forms yapılarına o kadar da yabancı değiliz. Önceki Angular Forms Uygulamaları başlıklı yazımda Angular uygulamalarında form yapılarına değinirken “Model Odaklı Formlar” ile bizzat Reactive Form yapılanmasını ele almış bulunmaktayız.

Şimdi gelin Angular 7 ile gelen Reactive Forms yapılarını baştan sona tekrar detaylıca ele alalım…
İlk olarak örnek bir Angular uygulaması ayağa kaldıralım. Ardından aşağıdaki tarifleri sırasıyla uygulamaya alalım;

Reactive Formların Uygulamaya Import Edilmesi

Uygulamamızda reactive formları kullanabilmek için yapılması gereken ilk işin uygulamaya ReactiveFormsModule modülünün import edilmesidir. Bu işlem için uygulamamızın ana modülüne ilgili kütüphaneyi aşağıdaki gibi import ediyoruz.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { ReactiveFormsModule } from "@angular/forms";

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

16. satırda görüldüğü üzere ReactiveFormsModule modülü uygulamaya import edilmiştir ve böylece uygulamada reactive formlar kullanılabilir hale gelmiştir.

FormBuilder Nesnesi İle Reactive Formun Tasarlanması

FormBuilder nesnesi, makalemizin ilk paragraflarından refere etmiş olduğum makale içeriğinde kullandığımız “FormGroup” ve “FormControl” gibi nesneleri kısa yoldan oluşturarak, basit bir şekilde kompleks form yapıları tasarlamamızı sağlayan bir servistir. Kullanımı aşağıdaki gibidir;

import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-reactive-forms-example',
  templateUrl: './reactive-forms-example.component.html',
  styleUrls: ['./reactive-forms-example.component.css']
})
export class ReactiveFormsExampleComponent implements OnInit {

  constructor(private formBuilder: FormBuilder) { }

  frmPerson: FormGroup;
  ngOnInit() {
    this.frmPerson = this.formBuilder.group({
      name: [""],
      surname: [""],
      email: [""],
      age: [""]
    });
  }

  get component() { return this.frmPerson.controls }

  onSubmit(data: Person) {
    console.log(data);
  }
}

export class Person {
  constructor(public name: string, public surname: string, public email: string) {

  }
}

Yukarıdaki örnek kod bloğunda 16 – 21. satırlar arasına göz atarsanız eğer constructor’dan inject edilen FormBuilder nesnesi üzerinden form modelimiz tasarlanmakta ve “FormGroup” tipinden “frmPerson” isimli değişkene atanmaktadır. Ayriyetten birazdan görsel kısımda ele alacağımız form binding neticesinde doldurulmuş veriyi post neticesinde “onSubmit” isimli fonksiyon 34 – 37. satırlar arasında tanımlanan “Person” sınıfı tipinden bir parametreyle otomatik mepper işlemi gerçekleştirerek karşılayacaktır.

FormBuilder nesnesi ile oluşturmuş olduğumuz bu form yapısının html componentlerle binding işlemi aşağıdaki gibi sağlanmaktadır.

<div class="jumbotron">
  <div class="container">
    <div class="row">
      <div class="col-md-6 offset-md-3">
        <form [formGroup]="frmPerson" (ngSubmit)="onSubmit(frmPerson.value)">
          <div class="form-group">
            <label>Name</label>
            <input type="text" formControlName="name" class="form-control" />
          </div>
          <div class="form-group">
            <label>Surname</label>
            <input type="text" formControlName="surname" class="form-control" />
          </div>
          <div class="form-group">
            <label>E-Mail</label>
            <input type="text" formControlName="email" class="form-control" />
          </div>
          <div class="form-group">
            <label>Age</label>
            <input type="number" formControlName="age" class="form-control" />
          </div>
          <div class="form-group">
            <button class="btn btn-primary">Sign up</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

Yukarıdaki inşayı test edersek sonuç olarak aşağıdaki ekran görüntüsünde olduğu gibi neticeyle karşılaşılmaktadır;
Angular 7 - Reactive Forms

Şimdi bu tasarladığımız forma “FormBuilder” nesnesinin sağladığı kolaylıktan istifade ederek validasyon işlemlerini uygulayalım.

Forma Validasyon Uygulanması

Forma validasyon uygulayabilmek için tasarımızda ve şablonumuzda aşağıdaki gibi bazı değişiklikler yapmamız gerekmektedir.

import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-reactive-forms-example',
  templateUrl: './reactive-forms-example.component.html',
  styleUrls: ['./reactive-forms-example.component.css']
})
export class ReactiveFormsExampleComponent implements OnInit {

  constructor(private formBuilder: FormBuilder) { }

  frmPerson: FormGroup;
  submitted: boolean;
  ngOnInit() {
    this.frmPerson = this.formBuilder.group({
      name: ["",
        [
          Validators.required,
          Validators.maxLength(10),
          Validators.minLength(5)
        ]],
      surname: ["", Validators.required],
      email: ["",
        Validators.compose([
          Validators.email,
          Validators.required
        ])],
      age: ["",
        [Validators.required,
        Validators.max(5),
        Validators.min(3)]]
    });
  }

  get component() { return this.frmPerson.controls }

  onSubmit(data: Person) {
    this.submitted = true;
    if (this.frmPerson.invalid)
      return;
    console.log(data);
  }
}

export class Person {
  constructor(public name: string, public surname: string, public email: string) {

  }
}

Yukarıdaki kod bloğunu incelerseniz eğer validasyon işlemlerinde FormBuilder nesnesinin dizi yapısından faydalanıldığı gibi “Validators” sınıfının “compose” metoduda kullanılabilmektedir.

<div class="jumbotron">
  <div class="container">
    <div class="row">
      <div class="col-md-6 offset-md-3">
        <form [formGroup]="frmPerson" (ngSubmit)="onSubmit(frmPerson.value)">
          <div class="form-group">
            <label>Name</label>
            <input type="text" formControlName="name" class="form-control"
              [ngClass]="{'is-invalid': submitted && component.name.errors}" />
            <div class="invalid-feedback" *ngIf="submitted && component.name.errors">
              <div *ngIf="component.name.errors.required">Please do not leave your name empty.</div>
            </div>
          </div>
          <div class="form-group">
            <label>Surname</label>
            <input type="text" formControlName="surname" class="form-control"
              [ngClass]="{'is-invalid': submitted && component.surname.errors}" />
            <div *ngIf="submitted && component.surname.errors" class="invalid-feedback">
              <div *ngIf="component.surname.errors.required">Please do not leave your surname empty.</div>
            </div>
          </div>
          <div class="form-group">
            <label>E-Mail</label>
            <input type="text" formControlName="email" class="form-control"
              [ngClass]="{'is-invalid': submitted && component.email.errors}" />
            <div *ngIf="submitted && component.email.errors" class="invalid-feedback">
              <div *ngIf="component.email.errors.required">Please do not leave your email empty.</div>
              <div *ngIf="component.email.errors.email">Please enter your e-mail address correctly.</div>
            </div>
          </div>
          <div class="form-group">
            <label>Age</label>
            <input type="number" formControlName="age" class="form-control"
              [ngClass]="{'is-invalid': submitted && component.age.errors}" />
            <div *ngIf="submitted && component.age.errors" class="invalid-feedback">
              <div *ngIf="component.age.errors.required">Please do not leave your age empty.</div>
              <div *ngIf="component.age.errors.maxLength">Up to 5</div>
            </div>
          </div>
          <div class="form-group">
            <button class="btn btn-primary">Sign up</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

İlgili çalışmayı sağladıktan sonra neticede aşağıdaki ekran görüntüsünde olduğu gibi bir sonuçla karşılaşılmaktadır.
Angular 7 - Reactive Forms

Detaylı Validasyon İncelemesi

FormBuilder ile tasarlayıp forma bind ettiğimiz yapı üzerinde validasyon sürecinin nasıl ceyran ettiğini detaylı incelemek için aşağıdaki optimizasyonu inceleyiniz;

    let nameError = this.component.name.errors;
    let surnameError = this.component.surname.errors;
    let emailError = this.component.email.errors;
    let age = this.component.age.errors;

Görüldüğü üzere formda bind edilen herhangi bir componentin validasyonu geçersiz olduğu durumda bizlere “errors” özelliği dolu gelmekte ve aşağıdaki ekran görüntüsünde olduğu gibi hangi validasyonlara takılındığıyla ilgili bilgi verilmektedir.

KontrolValidasyon
Angular 7 - Reactive Forms Angular 7 - Reactive Forms

Evet… İşte Angular 7 uygulamalarında Reactive Forms yapıları bu şekilde uygulanmaktadır.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar dilerim…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*

Copy Protected by Chetan's WP-Copyprotect.