Angular’da Dahili Borular (Pipes): Veri Dönüşümünde Güçlü Bir Araç
Giriş: Angular Pipes Nedir ve Neden Önemlidir?
Angular, modern ve ölçeklenebilir web uygulamaları geliştirmek için kullanılan güçlü bir ön yüz çerçevesidir. Bu çerçeve, geliştiricilere karmaşık kullanıcı arayüzlerini ve etkileşimli deneyimleri kolayca oluşturma imkanı sunar. Angular’ın sunduğu birçok özellikten biri de “Pipes” (Borular) mekanizmasıdır. Pipes, bir değeri şablonda (template) görüntülemeden önce dönüştürmek için kullanılan basit fonksiyonlardır. Temel olarak, bir veriyi alır, üzerinde belirli bir işlem yapar ve dönüştürülmüş çıktıyı döndürür. Bu, özellikle veri formatlama, filtreleme veya sıralama gibi yaygın görevler için şablonlarınızın temiz ve okunabilir kalmasını sağlar.
Pipes’ın önemi birkaç ana noktada yatmaktadır:
- Kod Tekrarını Azaltma: Aynı veri dönüşüm mantığını birden fazla yerde kullanmanız gerektiğinde, bu mantığı bir Pipe içine kapsülleyerek kod tekrarını önlersiniz.
- Şablon Temizliği: Bileşen sınıfınızda (component class) karmaşık veri işleme mantığı yazmak yerine, bu işlemleri şablonda Pipe kullanarak doğrudan uygulayabilirsiniz. Bu, bileşen kodunuzun iş mantığına odaklanmasını sağlarken, şablonun sadece verinin nasıl görüntüleneceğiyle ilgilenmesini sağlar.
- Okunabilirlik ve Bakım Kolaylığı:
{{ veri | pipeAdı }}gibi basit bir sözdizimi sayesinde, şablonunuzda verinin nasıl dönüştürüldüğünü anlamak çok daha kolay hale gelir. Bu da uygulamanın bakımını ve anlaşılırlığını artırır. - Modülerlik: Her Pipe, belirli bir görevi yerine getiren bağımsız bir birimdir. Bu modüler yapı, kodun daha düzenli olmasını sağlar.
- Performans İyileştirmeleri: Angular, Pure (Saf) Pipes’ı varsayılan olarak optimize eder. Bu, bir Pure Pipe’ın yalnızca giriş değeri değiştiğinde yeniden çalıştırıldığı anlamına gelir, bu da gereksiz hesaplamaları önleyerek performansı artırır.
Angular, birçok yaygın dönüşüm ihtiyacını karşılamak üzere önceden tanımlanmış, kullanıma hazır “Dahili Borular” (Built-in Pipes) ile birlikte gelir. Bu makalede, Angular’ın sunduğu bu dahili boruları detaylı bir şekilde inceleyecek, nasıl kullanıldıklarını örneklerle açıklayacak ve bu güçlü aracın uygulamanızda nasıl daha verimli kullanılabileceğine dair en iyi uygulamaları ele alacağız.
Angular Pipes’ın Temel Kavramları
Angular Pipes’ı etkin bir şekilde kullanabilmek için, onların temel çalışma prensiplerini ve sözdizimini anlamak kritik öneme sahiptir.
Pipe Sözdizimi ve Kullanımı
Bir Pipe kullanmak son derece basittir. Şablonunuzda, dönüştürmek istediğiniz değerin ardından dikey çizgi (|) operatörünü ve ardından Pipe adını eklersiniz.
{{ değer | pipeAdı }}
Örneğin, bir metni büyük harfe dönüştürmek için UpperCasePipe kullanabiliriz:
Orijinal Metin: {{ 'merhaba dünya' }}
Büyük Harfli Metin: {{ 'merhaba dünya' | uppercase }}
Bazı Pipes, davranışlarını özelleştirmek için parametreler alabilir. Parametreler, Pipe adının ardından iki nokta üst üste (:) ile ayrılır. Birden fazla parametre varsa, bunlar da iki nokta üst üste ile ayrılır:
{{ değer | pipeAdı:parametre1:parametre2 }}
Örneğin, bir sayıyı belirli bir ondalık basamak sayısıyla formatlamak için DecimalPipe kullanabiliriz:
Sayı: {{ 12345.6789 | number:'1.2-2' }}
Burada number Pipe’ı, 1.2-2 format parametresini almaktadır. Bu parametre, sayının en az 1 tam sayı basamağı, en az 2 ondalık basamak ve en fazla 2 ondalık basamak içermesi gerektiğini belirtir.
Pure (Saf) ve Impure (Saf Olmayan) Pipes
Angular Pipes, performans açısından iki ana kategoriye ayrılır: Pure (Saf) ve Impure (Saf Olmayan). Bu ayrım, Pipe’ın ne zaman yeniden çalıştırılacağını belirler ve uygulamanızın performansını doğrudan etkiler.
Pure Pipes
Varsayılan olarak, tüm Angular Pipes Pure’dur. Bir Pure Pipe, yalnızca giriş değeri değiştiğinde yeniden çalıştırılır. Angular, giriş değerlerinin referanslarını kontrol ederek bir değişikliğin olup olmadığını belirler.
- Giriş değeri bir ilkel tür (string, number, boolean, symbol) ise, değeri doğrudan karşılaştırılır.
- Giriş değeri bir nesne (object, array, function) ise, Angular yalnızca referansın değişip değişmediğini kontrol eder, nesnenin içindeki özelliklerin değişip değişmediğini kontrol etmez (sığ karşılaştırma).
Bu davranış, Pure Pipes’ın çok verimli olmasını sağlar çünkü gereksiz hesaplamaları önler. Çoğu dahili Pipe (örneğin DatePipe, CurrencyPipe, UpperCasePipe) Pure’dur.
Örneğin:
@Component({
selector: 'app-pure-example',
template:
Tarih: {{ myDate | date:'medium' }}
})
export class PureExampleComponent {
myDate: Date = new Date();
changeDateReference() {
this.myDate = new Date(); // Yeni referans, pipe çalışır
}
updateDateObject() {
this.myDate.setHours(this.myDate.getHours() + 1); // Referans aynı, pipe çalışmaz
console.log('Tarih nesnesi güncellendi, ancak referans değişmedi.');
}
}
updateDateObject() metodunu çağırdığınızda, myDate nesnesinin içeriği değişse bile, referansı değişmediği için DatePipe yeniden çalışmayacak ve şablonda gösterilen tarih güncellenmeyecektir. Bu, Pure Pipes’ın sığ karşılaştırma yapmasından kaynaklanır.
Impure Pipes
Impure Pipes, her algılama döngüsünde (change detection cycle) çalıştırılır. Bu, bir bileşenin herhangi bir özelliği değiştiğinde veya bir DOM olayı (tıklama, klavye girişi vb.) tetiklendiğinde bile Pipe’ın yeniden çalışacağı anlamına gelir. Impure Pipes, genellikle nesne referansları değişmeden nesnelerin içeriğindeki değişiklikleri izlemesi gereken durumlar için kullanılır.
AsyncPipe ve JsonPipe gibi bazı dahili Pipes Impure’dur. Kendi Impure Pipe’ınızı oluşturmak için, @Pipe dekoratörüne pure: false özelliğini eklemeniz gerekir.
Impure Pipes’ın her algılama döngüsünde çalışması, performans üzerinde olumsuz bir etki yaratabilir, özellikle de Pipe içinde karmaşık veya yoğun hesaplamalar yapılıyorsa. Bu nedenle, Impure Pipes dikkatli kullanılmalı ve yalnızca gerçekten ihtiyaç duyulduğunda tercih edilmelidir.
Pipe Zincirleme ve Parametre Kullanımı
Angular Pipes’ın güçlü özelliklerinden biri de birden fazla Pipe’ı ardışık olarak kullanabilme yeteneğidir. Buna “Pipe Zincirleme” denir. Bir Pipe’ın çıktısı, bir sonraki Pipe’ın girdisi haline gelir.
{{ değer | pipeAdı1:parametre1 | pipeAdı2:parametre2 }}
Örneğin, bir metni önce dilimleyip sonra büyük harfe dönüştürebilirsiniz:
Zincirlenmiş Pipe: {{ 'angular framework' | slice:0:7 | uppercase }}
Burada, slice:0:7 Pipe’ı ‘angular framework’ metnini ‘angular’ olarak dönüştürür ve bu çıktı uppercase Pipe’ına girdi olarak verilir, sonuç olarak ‘ANGULAR’ elde edilir.
Parametreler, Pipe’ın davranışını özelleştirmek için kullanılır. Her Pipe’ın kendi özel parametreleri olabilir ve bu parametreler genellikle isteğe bağlıdır. Parametrelerin doğru format ve değerlerle kullanılması, Pipe’ın beklenen çıktıyı vermesini sağlar.
Angular’ın Dahili Boruları: Detaylı İnceleme ve Kullanım Örnekleri
Angular, birçok yaygın veri dönüşüm senaryosu için kullanışlı dahili borular sağlar. Bu bölümde, en sık kullanılan dahili boruları ayrıntılı olarak inceleyeceğiz.
Metin Dönüşüm Boruları
Metin tabanlı verileri formatlamak için kullanılan borulardır.
UpperCasePipe
Bir metni tamamen büyük harfe dönüştürür.
Normal: {{ 'angular' }}
Büyük Harf: {{ 'angular' | uppercase }}
LowerCasePipe
Bir metni tamamen küçük harfe dönüştürür.
Normal: {{ 'ANGULAR' }}
Küçük Harf: {{ 'ANGULAR' | lowercase }}
TitleCasePipe
Bir metindeki her kelimenin ilk harfini büyük harfe dönüştürür ve diğer harfleri küçük harfe ayarlar.
Başlık Durumu: {{ 'angular framework' | titlecase }}
SlicePipe
Bir dizinin veya metin dizisinin belirli bir bölümünü döndürür. İki isteğe bağlı parametre alır: start (başlangıç indeksi) ve end (bitiş indeksi). end parametresi dahil değildir.
Dilimlenmiş Metin: {{ 'Merhaba Dünya' | slice:0:7 }}
Sondan Başlayan Dilim: {{ 'Angular' | slice:-3 }}
Diziden Dilim: {{ ['elma', 'armut', 'muz', 'çilek'] | slice:1:3 }}
JsonPipe
Bir JavaScript değerini (nesne, dizi vb.) JSON formatında bir metin dizisine dönüştürür. Özellikle hata ayıklama (debugging) sırasında nesnelerin içeriğini hızlıca görüntülemek için kullanışlıdır.
{{ { isim: 'Ali', yaş: 30, şehir: 'Ankara' } | json }}
JsonPipeImpure bir Pipe’tır, yani nesnenin içeriği değiştiğinde otomatik olarak güncellenir.Sayı Dönüşüm Boruları
Sayısal verileri formatlamak için kullanılır.
DecimalPipe
Bir sayıyı yerel ayara (locale) göre formatlar. Minimum ve maksimum tam sayı/ondalık basamak sayılarını belirten bir format dizesi alır:
'{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}'.Sayı Formatı 1: {{ 12345.6789 | number }}
Sayı Formatı 2: {{ 12345.6789 | number:'1.2-2' }}
Sayı Formatı 3: {{ 123.4 | number:'2.0-0' }}
Format dizesi:
minIntegerDigits: Tam sayı kısmının minimum basamak sayısı. Eğer sayı daha az basamaklıysa, önüne sıfır eklenir.minFractionDigits: Ondalık kısmının minimum basamak sayısı. Eğer sayı daha az basamaklıysa, sonuna sıfır eklenir.maxFractionDigits: Ondalık kısmının maksimum basamak sayısı. Sayı bu basamak sayısından fazlaysa yuvarlanır.
PercentPipe
Bir sayıyı yüzde formatına dönüştürür (1.0 = %100). DecimalPipe ile aynı format dizesi parametresini alır.
Yüzde Formatı 1: {{ 0.25 | percent }}
Yüzde Formatı 2: {{ 0.735 | percent:'1.1-1' }}
CurrencyPipe
Bir sayıyı para birimi formatına dönüştürür. Dört isteğe bağlı parametre alır: currencyCode, display (görüntüleme şekli), digitsInfo (ondalık basamak formatı) ve locale.
Para Birimi 1: {{ 1234.56 | currency }}
Para Birimi 2: {{ 1234.56 | currency:'EUR' }}
Para Birimi 3: {{ 1234.56 | currency:'TRY':'symbol':'1.2-2' }}
Para Birimi 4: {{ 1234.56 | currency:'GBP':'code' }}
display parametresi için olası değerler:
'symbol'(varsayılan): Para birimi sembolü (örn. $).'code': ISO 4217 para birimi kodu (örn. USD).'symbol-narrow': Dar para birimi sembolü (örn. $).'name': Para biriminin tam adı (örn. US dollars).'false': Hiçbir sembol veya kod göstermez.
Tarih Dönüşüm Boruları
Tarih ve saat verilerini formatlamak için kullanılır.
DatePipe
Bir tarihi veya zamanı yerel ayara göre formatlar. En esnek ve karmaşık dahili Pipe’lardan biridir. İki isteğe bağlı parametre alır: format dizesi ve timezone.
Varsayılan Tarih: {{ myDate | date }}
Kısa Tarih: {{ myDate | date:'shortDate' }}
Tam Tarih ve Saat: {{ myDate | date:'full' }}
Özel Format: {{ myDate | date:'dd/MM/yyyy HH:mm:ss' }}
Zaman Dilimi: {{ myDate | date:'medium':'+0500' }}
format parametresi için birçok önceden tanımlanmış format dizesi (örn. 'short', 'medium', 'long', 'full', 'shortDate', 'mediumDate', 'longDate', 'fullDate', 'shortTime', 'mediumTime', 'longTime', 'fullTime') veya özel bir format dizesi kullanabilirsiniz. Özel format dizesi, aşağıdaki gibi harflerin bir kombinasyonudur:
y: Yıl (örn. 2023)yy: Yılın son iki hanesi (örn. 23)yyyy: Dört haneli yıl (örn. 2023)M: Ay (1-12)MM: İki haneli ay (01-12)MMM: Ayın kısa adı (örn. Eyl)MMMM: Ayın tam adı (örn. Eylül)d: Gün (1-31)dd: İki haneli gün (01-31)E: Haftanın günü kısa adı (örn. Paz)EEEE: Haftanın günü tam adı (örn. Pazar)h: Saat (1-12)hh: İki haneli saat (01-12)H: Saat (0-23)HH: İki haneli saat (00-23)m: Dakika (0-59)mm: İki haneli dakika (00-59)s: Saniye (0-59)ss: İki haneli saniye (00-59)a: AM/PM göstergesiz: Zaman dilimi kısa adızzz: Zaman dilimi tam adı
Asenkron Veri Yönetimi Boruları
Asenkron verileri (Promises ve Observables) yönetmek için kullanılır.
AsyncPipe
Bir Promise veya Observable’a abone olur ve en son yayımlanan değerini döndürür. Bileşen yok edildiğinde (destroyed) otomatik olarak aboneliği iptal eder, bu da bellek sızıntılarını önler.
@Component({
selector: 'app-async-example',
template:
Promise Verisi: {{ myPromise | async }}
Observable Verisi: {{ myObservable | async }}
Observable'dan gelen veri: {{ data }}
})
export class AsyncExampleComponent implements OnInit {
myPromise: Promise;
myObservable: Observable;
data$: Observable;
ngOnInit() {
this.myPromise = Promise.resolve('Promise Tamamlandı!');
this.myObservable = of(1, 2, 3).pipe(delay(1000)); // 1 saniye sonra 1,2,3 yayımlar
this.data$ = interval(1000).pipe(map(i => Veri ${i + 1}), take(5)); // Her saniye yeni veri yayımlar
}
}
AsyncPipe Impure bir Pipe’tır çünkü abone olduğu Observable veya Promise’dan yeni değerler geldiğinde her zaman çalışması gerekir. Bu Pipe, Angular uygulamalarında asenkron veri akışlarını yönetmenin en temiz ve en güvenli yollarından biridir. *ngIf ile birlikte kullanılması, verinin gelmesini beklerken UI’da placeholder gösterme gibi senaryolarda çok yaygındır.
Diğer Faydalı Dahili Borular
KeyValuePipe
Bir nesneyi veya Map‘i anahtar-değer çiftleri dizisine dönüştürür. Bu, *ngFor ile bir nesnenin veya Map‘in özelliklerini kolayca yinelemenizi sağlar. İsteğe bağlı bir compareFn (karşılaştırma fonksiyonu) parametresi alır.
Anahtar: {{ entry.key }}, Değer: {{ entry.value }}
KeyValuePipe varsayılan olarak anahtarları artan sıraya göre sıralar. Sıralama düzenini değiştirmek için özel bir karşılaştırma fonksiyonu sağlayabilirsiniz.
Angular Pipes Kullanımında En İyi Uygulamalar ve Dikkat Edilmesi Gerekenler
Pipes, Angular geliştiricileri için son derece güçlü bir araçtır, ancak performans ve bakım kolaylığı açısından bazı en iyi uygulamaları ve dikkat edilmesi gereken noktaları göz önünde bulundurmak önemlidir.
Performans ve Pure/Impure Pipes Seçimi
* Pure Pipes’ı Tercih Edin: Mümkün olduğunca Pure Pipes kullanın. Bunlar, yalnızca giriş değerleri (referansları) değiştiğinde yeniden çalıştırıldıkları için performans açısından çok daha verimlidir. Çoğu veri formatlama ihtiyacı Pure Pipes ile karşılanabilir.
* Impure Pipes’ı Dikkatli Kullanın: Impure Pipes her algılama döngüsünde çalışır. Bu, uygulamanızın performansını olumsuz etkileyebilir, özellikle de çok sayıda Impure Pipe’ınız varsa veya Pipe içindeki mantık karmaşıksa. Yalnızca gerçekten nesne içeriğindeki değişiklikleri izlemeniz gerektiğinde (AsyncPipe gibi) veya özel bir nedeniniz olduğunda Impure Pipe kullanın. Kendi Impure Pipe’ınızı oluştururken, içinde yapılan işlemlerin hafif olduğundan emin olun.
Pipes mı, Component Metotları mı?
Bazen bir veriyi dönüştürmek için bir Pipe mı yoksa bileşen içinde bir metot mu kullanmanız gerektiği konusunda tereddüt edebilirsiniz. İşte karar vermenize yardımcı olacak bazı yönergeler:
* Pipes Kullanın:
* Dönüşüm mantığı safsa (yani, aynı girdi her zaman aynı çıktıyı veriyorsa ve dış duruma bağımlı değilse).
* Dönüşüm mantığı birden fazla şablonda veya bileşende tekrar kullanılıyorsa.
* Dönüşüm mantığı nispeten basit ve hızlıysa.
* Şablonun daha temiz ve okunabilir olmasını istiyorsanız.
* Component Metotları veya Getters Kullanın:
* Dönüşüm mantığı Impure ise (yani, dış duruma bağımlıysa veya yan etkileri varsa).
* Dönüşüm mantığı karmaşık ve performans yoğunsa.
* Dönüşüm sadece belirli bir bileşen içinde bir kez kullanılıyorsa.
* Dönüşüm, kullanıcının etkileşimine veya diğer bileşen durumlarına bağlıysa.
Unutmayın ki bir bileşen metodunu şablonda çağırmak, her algılama döngüsünde metodun yeniden çalışmasına neden olur. Bu da özellikle karmaşık metotlar için performans sorunlarına yol açabilir. Bu nedenle, Pure Pipes genellikle daha güvenli bir seçenektir.
Uluslararasılaşma (i18n) ve Yerel Ayarlar
Angular’ın dahili Pipes’ı (özellikle DatePipe, DecimalPipe, CurrencyPipe, PercentPipe) uluslararasılaşma (i18n) yetenekleriyle entegre edilmiştir. Bu, farklı diller ve bölgeler için doğru formatlamayı sağlamak üzere uygulamanızın yerel ayarını (locale) kullanacakları anlamına gelir.
* Uygulamanızın varsayılan yerel ayarını APP_INITIALIZER veya LOCALE_ID sağlayıcısını kullanarak ayarlayabilirsiniz. Örneğin, app.module.ts dosyasında registerLocaleData(localeTr, 'tr'); çağrısı yaparak ve [{ provide: LOCALE_ID, useValue: 'tr' }] sağlayarak Türkçeyi varsayılan yerel ayar yapabilirsiniz.
* Pipes, bu yerel ayar bilgilerini otomatik olarak kullanarak tarihleri, sayıları ve para birimlerini doğru formatta görüntüler (örn. Türkiye için virgül ondalık ayırıcı, nokta binlik ayırıcı).
* Bazı Pipes (örn. DatePipe, CurrencyPipe) isteğe bağlı olarak doğrudan bir locale parametresi alabilir, bu da varsayılan yerel ayarı geçersiz kılmanıza olanak tanır.
Okunabilirlik ve Bakım Kolaylığı
* Anlamlı Pipe Adları: Kendi özel Pipe’larınızı oluştururken, Pipe’ın amacını açıkça belirten anlamlı adlar kullanın.
* Basit Mantık: Pipes’ın içinde karmaşık iş mantığı yerine, tek ve odaklanmış bir dönüşüm görevi yapmasını sağlayın. Karmaşık mantık genellikle servislerde veya bileşenlerde daha iyi yer alır.
* Aşırı Zincirlemeden Kaçının: Çok fazla Pipe’ı zincirlemek şablonunuzu okunaksız hale getirebilir. Eğer bir veri üzerinde çok sayıda ardışık dönüşüm yapmanız gerekiyorsa, bu dönüşümleri bir bileşen metodunda veya özel bir Pipe içinde birleştirmeyi düşünebilirsiniz.
Sonuç
Angular’ın dahili boruları (Pipes), uygulamalarınızdaki veri dönüşüm ihtiyaçlarını karşılamak için güçlü, esnek ve verimli bir mekanizma sunar. DatePipe ile tarihleri formatlamaktan, CurrencyPipe ile para birimlerini görüntülemeye, AsyncPipe ile asenkron verileri yönetmeye kadar geniş bir yelpazede kullanışlılık sağlarlar.
Pipes kullanarak, bileşen sınıflarınızı temiz tutabilir, şablonlarınızın okunabilirliğini artırabilir ve veri formatlama mantığını yeniden kullanılabilir, modüler birimler halinde kapsülleyebilirsiniz. Pure ve Impure Pipes arasındaki farkı anlamak ve bunları doğru senaryolarda kullanmak, uygulamanızın performansını optimize etmenin anahtarıdır. Ayrıca, Pipes’ın uluslararasılaşma (i18n) yetenekleriyle entegre olması, küresel kullanıcılar için yerelleştirilmiş deneyimler sunmanızı kolaylaştırır.
Angular geliştiricileri olarak, bu dahili boruları etkin bir şekilde kullanmak, daha temiz, daha sürdürülebilir ve daha performanslı uygulamalar yazmanıza yardımcı olacaktır. Dahili boruların yetersiz kaldığı durumlarda ise kendi özel borularınızı oluşturarak Angular’ın bu güçlü özelliğini daha da genişletebilirsiniz. Unutmayın, iyi kullanılmış Pipes, Angular şablonlarınızı hem daha güçlü hem de daha zarif hale getirir.
