· Özgür Vurgun · Angular · 2 min read

8. Componentler Arası Veri Akışı

8. Componentler Arası Veri Akışı

Angular’da Bileşenler Konuşur mu?

Bileşenlerinizi oluşturuyorsunuz:

  • AppComponent
  • NavbarComponent
  • UserCardComponent
  • TodoListComponent

Ama bir sorun var: Bunlar yalnızca görüntü mü veriyor, yoska birbirleriyle konuşabiliyorlar mı? Cevap: Evet konuşabilirler. Ama sadece belirli yollarla.

Angular’ın Felsefesi: Tek Yönlü Veri Akışı

Angular’da veri akışı: Parent ➡️ Child

Yani üst bileşen, alt bileşene veri gönderir. Tersini yapmak istersen, child bileşen sadece bir event fırlatabilir.

“Benim içimde bir şey oldu, haberin olsun” der.

Bu mekanizma için 2 araç kullanırız:

  • @Input() parent’tan child’a veri gönderir
  • @Output() child’tan parent’a event fırlatır

@Input() - İçeri Veri Almak

  • Kullanım senaryosu: UserCardComponent içinde kullanıcı bilgisini göstermek istiyorsun. Ama bu bilgi AppComponent’ te duruyor.

Child Component (user-card.component.ts)

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-user-card',
  template: `<p>{{ user.name }}</p>`
})

export class UserCardComponent {
  @Input() user: any;
}

Parent Component

<app-user-card [user]="activeUser"></app-user-card>

[user] Angular’a der ki: “Bu attribute sabit bir string değil, bir değişken.”

@Output() - Dışarı Event Göndermek

Şimdi de tersine bakalım:

UserCardComponent içinde bir buton var ve basıldığında parent bir aksiyon alsın istiyorsun.

Child Component

import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-user-card',
  template: `<button (click)="selectUser()">Seç</button>`
})
export class UserCardComponent {
  @Output() selected = new EventEmitter<void>();

  selectUser() {
    this.selected.emit(); // olay fırlatıldı
  }
}

Parent Component

<app-user-card (selected)="handleUserSelected()"></app-user-card>

Parent bileşen olayı dinler ve handleUserSelected() fonksiyonunu çalıştırır.

Veri Akışı Özet Dİyagram

  • Parent ➡️ @Input ➡️ Child
  • Child ➡️ @Output ➡️ Parent

Parametreli @Output

Evet sadece boş değil, veri taşıyarak da fırlatılabilir.

@Output() selected = new EventEmitter<number>();

selectUser() {
  this.selected.emit(this.user.id);
}
<app-user-card (selected)="handleSelection($event)"></app-user-card>

Parent bileşen $event parametresi, emit edlien değeri taşır.

Sık Yapılan Hatalar

  • @Input ile gelen veriyi doprudan değiştirmek (anti pattern)
  • @Output’ u event gibi değil, veri gibi kullanmaya çalışmak
  • EventEmitter‘ı servis içinde kullanmak (gereksiz)
  • Parent verisi daha geç geliyorsa undefined hatası -> ? operatörü kullan: user?.name

@Input İle @ Output Ne Zaman Yeterli Gelmez?

Eğer veri paylaşımı:

  • Çok sayıda bileşen arasında oluyorsa
  • Aralrında parent-child ilşkisi yoksa
  • App-wide state gerekiyorsa

O zaman Service + Dependency Injection kullanmak gerekiyor. (Hatta daha büyük projelerde state management library (NGRX, Akita) gibi çözümler)

Alternatif Yöntemler

İhtiyaçÇözümParent ↔️ Child iletişimi@Input() & @Output()Sibling ↔️ Sibling iletişimi (kardeşler)Ortak Service + Subject / RxJSComponent ➡️ Global iletişimState Management (NGRX, Signal)

Özet

  • @Input -> veri gönder
  • @Output -> event fırlat
  • Tek yönlü veri akışı Angular’ın temel ilkesidir
  • Karmaşık iletişimde Service kullanılır
Share:
Back to Blog

Related Posts

View All Posts »
3. First Component

3. First Component

Angular ile yeni bir component oluşturmak için şu komutu verirsin or bu kadar :)

18. Monorepo Nedir?

18. Monorepo Nedir?

Ne Bu Monorepo? Projeyi yazıyorsun, her şey yolunda. Sonra ekip büyüyor. Frontend bir yerde, backend başka yerde, ortak UI bileşenleri başka bir repo’da… Bir noktada kendini şöyle...

16. Zoneless Nedir?

16. Zoneless Nedir?

Angular deyince akla genelde component’ler, service’ler falan gelir ama içerde bir mimari var ki, senin haberin bile olmadan bütün uygulamanın kaderini etkiliyor: Zone.js Bu...