Angular, uygulama geliştiricilerinin kullanıcı formları oluşturmasına yardımcı olmak için iki farklı yaklaşım sunar: Template-driven formlar ve Reactive formlar. Her iki yaklaşımın da avantajları ve dezavantajları vardır. Şimdi bu iki yaklaşımı ayrıntılı bir şekilde inceleyelim.
1. Template-Driven Formlar
Template-driven formlar, Angular’da form oluşturmanın en basit yoludur. HTML şablon içinde doğrudan form elemanlarıyla çalışmayı tercih edenler için uygundur.
Özellikleri:
Two-Way Data Binding: NgModel kullanılarak iki yönlü veri bağlama yapısını kullanır. Bu, form elemanının değeri ve bileşenin ilgili özelliği arasında otomatik bir senkronizasyon sağlar.
Minimal Kod: Template-driven formlarda, çoğunlukla şablon koduyla ilgilenirsiniz. Bu, basit formlar için hızlı ve kolay bir yol sunar.
Otomatik Form Modeli Oluşturma: Angular, şablonu kullanarak otomatik olarak form modelini oluşturur.
Şimdi template-driven form kullanarak basit bir register uygulaması yapalım.
Modül Tanımlamaları (app.module.ts)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { UserService } from './user.service'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FormsModule // Eklendi ], providers: [UserService], bootstrap: [AppComponent] }) export class AppModule { } |
HTML Şablonu (app.component.html)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)" novalidate> <div> <label for="username">Kullanıcı Adı:</label> <input type="text" id="username" name="username" [(ngModel)]="user.username" required> <span *ngIf="userForm.controls.username?.invalid && userForm.controls.username?.touched">Kullanıcı adı gereklidir!</span> </div> <div> <label for="email">E-mail:</label> <input type="email" id="email" name="email" [(ngModel)]="user.email" required email> <span *ngIf="userForm.controls.email?.errors?.required && userForm.controls.email?.touched">E-mail gereklidir!</span> <span *ngIf="userForm.controls.email?.errors?.email && userForm.controls.email?.touched">Geçerli bir e-mail giriniz!</span> </div> <button [disabled]="userForm.invalid" type="submit">Kaydol</button> </form> |
Bileşen Kodu (app.component.ts)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import { Component } from '@angular/core'; import { UserService } from './user.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { user = { username: '', email: '' }; constructor(private userService: UserService) { } onSubmit(form) { if (form.valid) { this.userService.register(this.user).subscribe(response => { console.log("Kayıt başarılı!", response); }); } } } |
Servis (user.service.ts)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class UserService { private apiUrl = 'http://localhost:3001/api/users'; constructor(private http: HttpClient) { } register(userData): Observable<any> { return this.http.post(this.apiUrl, userData); } } |
Bu örnekte neler yaptık?
app.module.ts: FormsModule’u ekledik ve servisimizi sağladık.
app.component.html: Template-driven form oluşturduk. Doğrulama mesajlarını form alanlarının geçerli olup olmadığına göre gösterdik.
app.component.ts: onSubmit metoduyla form gönderildiğinde servisimizi çağırdık.
user.service.ts: Basit bir HTTP istemci servisi oluşturduk.
2. Reactive Formlar
Reactive formlar, daha karmaşık ve özelleştirilebilir form ihtiyaçları için önerilen yaklaşımdır. Reactive formlarla, bileşen kodu üzerinden programatik olarak form kontrolünü tamamen ele alabilirsiniz.
Özellikleri:
Esneklik: Formunuzu programatik olarak oluşturabileceğiniz için kompleks formlarda daha çok esneklik sağlar.
Değişiklikleri Takip: FormGrup ve FormControl gibi yapılar, formdaki değişiklikleri dinlemek ve tepki vermek için kullanılır.
Erişim: Reactive formlar, formun her bir parçasına doğrudan erişim sağlar.
Validatorler: Reactive formlar, özel validatorler oluşturarak veya Angular’ın sağladığı validatorleri kullanarak form girişlerini doğrulamak için kullanılır.
Şimdi, yukarıda template-driven formlar ile yaptığımız örneğin aynısını burada reactive formlar ile yapalım.
Modül Tanımlamaları (app.module.ts)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { UserService } from './user.service'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, ReactiveFormsModule // Eklendi ], providers: [UserService], bootstrap: [AppComponent] }) export class AppModule { } |
HTML Şablonu (app.component.html)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<form [formGroup]="userForm" (ngSubmit)="onSubmit()"> <div> <label for="username">Kullanıcı Adı:</label> <input type="text" id="username" formControlName="username"> <span *ngIf="userForm.get('username').invalid && userForm.get('username').touched">Kullanıcı adı gereklidir!</span> </div> <div> <label for="email">E-mail:</label> <input type="email" id="email" formControlName="email"> <span *ngIf="userForm.get('email').errors?.required && userForm.get('email').touched">E-mail gereklidir!</span> <span *ngIf="userForm.get('email').errors?.email && userForm.get('email').touched">Geçerli bir e-mail giriniz!</span> </div> <button type="submit">Kaydol</button> </form> |
Bileşen Kodu (app.component.ts)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { UserService } from './user.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { userForm: FormGroup; constructor(private fb: FormBuilder, private userService: UserService) { } ngOnInit() { this.userForm = this.fb.group({ username: ['', Validators.required], email: ['', [Validators.required, Validators.email]] }); } onSubmit() { if (this.userForm.valid) { this.userService.register(this.userForm.value).subscribe(response => { console.log("Kayıt başarılı!", response); }); } } } |
Servis (user.service.ts)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class UserService { private apiUrl = 'http://localhost:3001/api/users'; constructor(private http: HttpClient) { } register(userData): Observable<any> { return this.http.post(this.apiUrl, userData); } } |
Bu örnekte neler yaptık?
app.module.ts: ReactiveFormsModule’u projeye ekledik.
app.component.html: Reactive form kullanarak şablonu oluşturduk. Doğrulama hatalarını kontrol etmek için formGroup ve formControlName direktiflerini kullandık.
app.component.ts: FormBuilder kullanarak formumuzu oluşturduk ve doğrulamaları ekledik. onSubmit metodu ile formun geçerli olup olmadığını kontrol ediyoruz.
user.service.ts: Basit bir HTTP istemci servisi oluşturduk.
Hangisini Seçmeliyim?
Eğer basit bir form oluşturacaksanız ve kod tarafında çok fazla kontrol ve özelleştirmeye ihtiyaç duymuyorsanız, Template-driven formlar idealdir.
Fakat formunuzun karmaşık olacağını, özel doğrulamalara veya dinamik form alanlarına ihtiyaç duyacağınızı düşünüyorsanız, Reactive yaklaşımını tercih etmelisiniz.
Umarım “Angular Form İşlemleri: Template-driven ve Reactive Formlar” başlıklı yazım sizin için faydalı olmuştur.
Şu yazılar da ilginizi çekebilir.
Angular HTTP İstekleri ve RxJS
Yeni bir yazımda görüşmek üzere.
Happy coding!