Angular – output() API
Merhaba,
Bu içeriğimizde, Angular mimarisinde parent component’lere değer emit’lememizi sağlayan geleneksel Output decorator’ının yerine geçecek olan output() API yapısını inceleyeceğiz.
output() API yapısı davranışsal olarak output() ve outputFromObservable() fonksiyonlarıyla hayatımıza girmiştir. output() fonksiyonu, bizlere emit’lenebilir bir output yapısı sunarken, outputFromObservable() fonksiyonu ise observable olarak bir kaynak yayınlayan ve subscribe olunabilen output sunmaktadır.
Şimdi gelin bu iki fonksiyonu hususi olarak incelemeye başlayalım;
- output()
output() fonksiyonuna erişebilmek için@angular/corepath’inden aşağıdaki gibi import edilmesi gerekmektedir;import { output } from '@angular/core';Child component’ten bir değeri emit’leyebilmek için ise aşağıdaki gibi tanımlamanın yapılması ve kullanılması yeterlidir;
@Component({ selector: 'app-book', standalone: true, template: ` <button (click)="deleteBook(1)">Delete Book</button> ` }) export class BookComponent { deleteBookEmitter = output<Book>(); deleteBook(id: number) { const book: Book = new Book(); book.bookId = id; this.deleteBookEmitter.emit(book) } }Sonrasında ise parent component’te de bilinen mantıkla aşağıdaki gibi ilgili output’a bir event bind edilmelidir;
@Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet, BookComponent], template: ` <app-book (deleteBookEmitter)="deleteBookEvent($event)"></app-book> ` }) export class AppComponent { deleteBookEvent(book: Book) { console.log(book); } }İşte output() api’sinin kullanımı bu kadar basittir.
- outputFromObservable()
Angular mimarisi, output() api’sine ek olarak RxJS’i kusursuz bir şekilde entegre eden outputFromObservable() fonksiyonunu da sunmaktadır. Bu fonksiyona erişim için@angular/core/rxjs-interoppath’i üzerinden aşağıdaki gibi import gerçekleştirilebilir;import { outputFromObservable } from '@angular/core/rxjs-interop';Ve aşağıdaki gibi bir observable kaynağı yayan output oluşturulabilir;
@Component({...}) export class BookComponent { deleteBook$ = outputFromObservable<Book>(of<Book[]>({ bookId: 1 }, { bookId: 2 }, { bookId: 3 })); }Ardından da parent component’te bu output aşağıdaki gibi tüketilebilir;
@Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet, BookComponent], template: ` <app-book (deleteBook$)="deleteBookEvent($event)"></app-book> ` }) export class AppComponent { deleteBookEvent(book: Book) { console.log(book); } }Nasıl, harika değil mi?
Neden output() Fonksiyonunu Kullanmalıyız?
@Output decorator’ına nazaran neden output() api’sini kullanmamız gerektiğine dair kısa bir istişare yapmamız gerekirse eğer; basit olmaları, input signal ve model input gibi yeni fonksiyon tabanlı api’lerle kavramsal uyuma sahip olmaları ve mevcut EventEmitter sınıfının uzun süredir devam eden bir sorununu ele alarak yeni çıktılar için tür güvenliğini iyileştirerek emit operasyonunun tamamen tür güvenli hale getirilmesi ve bunun yanında observable olarak tasarlanabilmesi geleneksel @Output decorator’ına karşın output() api’sini tercih etmemiz gerektiğine dair haklı gerekçelerdir diyebiliriz.
Bu yeni API; her ne kadar Input Signals ve Model Inputs özelliklerine benziyor olsa da esasında bir signal değildir ve sadece yapısal olarak kalıplaşmış kodları azaltmamızı ve daha ergonomik bir kod inşa etmemizi sağlayan güzel bir özelliktir.
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…
