Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Angular’da Component Metotlarının Pipe Olarak Kullanılması

Merhaba,

Bu içeriğimizde, Angular mimarisinde, component metotlarını template içerisinde bir pipe misali kullanabilmemizi sağlayacak olan özel bir yöntemi ele alıyor olacağız. Bu yöntem, içeriğimizde de göreceğimiz üzere yine bir pipe üzerinden JavaScript ile yapılan bir manevraya dayanıyor olacaktır.

Evet, biliyorsunuz ki, Angular’da component metotlarını template içerisinde doğrudan pipe olarak kullanmamız normal şartlarda pek mümkün değildir. Şöyle ki;

  getDotColor(status: string): string {
    return status === 'active' ? 'green' : 'red';
  }

yukarıdaki gibi bir metodu aşağıdaki gibi kullanmak istersek eğer,

{{status : getDotColor}}

evet, bu tarz bir kullanım isteyebiliriz belki ancak, bu şekilde component metotlarının pipe misali kullanılması Angular’da söz konusu olamayacağı için ister istemez derleyici hatasıyla karşılaşacağız.

Amma velakin, component metotlarının bu şekilde pipe misali kullanılabildiğini varsayarsak eğer bunun oldukça etkili ve efektif bir yöntem olacağı aşikardır diyebiliriz. Düşünsenize, sıradan bir metodun işlevselliğini template üzerinde syntactic sugar olarak dönüşüm amaçlı kullanabilmekteyiz. Evet, bu çok tadında bir kullanım olsa gerek…

Peki bunun için ne yapabiliriz? diye sorduğumuzda aşağıdaki gibi component metotlarını pipe gibi kullanabilmek için bizim adımıza sorumluluğu üstlenecek olan özelleştirilmiş bir pipe oluşturmak gayet yerinde bir cevap olabilir;

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'templateMethod'
})
export class TemplateMethodPipe implements PipeTransform {
  transform<T>(value: unknown, handler: (value: any) => T, context?: any): unknown {
    if (context)
      return handler.call(context, value);

    return handler(value);
  }
}

Tasarladığımız bu pipe’ı incelersek eğer; template üzerinde uygulandığı veriyi value ile karşılamakta ve artık transform için hangi component metodu kullanılacaksa bunu da handler parametresiyle temsil etmektedir. Ee bir yandan da bu pipe, template üzerinde çağrıldığında handler parametresi üzerinden farklı bir metot devreye sokacağı için bu noktada bağlama göre this davranışının yönetilebilmesi maksadıyla context parametresi kullanılmaktadır. Bunun nedeni de, Java ve C# gibi dillerde yazıldığı sınıfa bağlılık göstermesinden aşina olduğumuz this keyword’ünün, JavaScript’te ise lexical scope (yazıldığı yer) değil de call-site (çağrıldığı yer) ile belirleniyor olmasındandır.

Velhasıl, bu TemplateMethodPipe isimli pipe’ı kullandığımız noktada value ile temsil edilen veri, handler ile tanımlanmış fonksiyona parametre olarak gönderilecek ve gerekli dönüşüm o anki context üzerinden gerçekleştirilecektir.

import { Component, signal } from '@angular/core';
import { TemplateMethodPipe } from './pipes/template-method-pipe';

@Component({
  selector: 'app-root',
  imports: [TemplateMethodPipe],
  template: `
  <span [style.color]="status() | templateMethod: getDotColor : this">
    ●
  </span>
  `
})
export class App {
  // status = signal('active');
  status = signal('passive');
  getDotColor(status: string): string {
    return status === 'active' ? 'green' : 'red';
  }
}

Nasıl ama? 🙂 Güzel bir taktik değil mi?

Hadi gelin bir örnek daha yapalım. Şimdi de aşağıdaki gibi bir image nesnesini bu pipe aracılığıyla component metot ile yapılandıralım…

  getImageUrl([width, height]: [number, number]): string {
    return `https://****.jpg?w=${width}&h=${height}`;
  }

Yukarıdaki metodu incelerseniz, verilen parametre değerlerine göre herhangi bir görseli yapılandırmaktadır. Bunu TemplateMethodPipe aracılığıyla aşağıdaki gibi oldukça konforlu bir şekilde kullanabiliriz;

<img [src]="[400, 500] | templateMethod: getImageUrl : this">

ya da bu component metottaki parametre aşağıdaki gibi bir object’te olabilir;

  getImageUrlObject({ width, height }: { width: number, height: number }): string {
    return `https://static.scientificamerican.com/sciam/cache/file/9500DFFF-C2CB-4B66-839718537F898FFD_source.jpg?w=${width}&h=${height}`;
  }
  <img [src]="{width:400, height:500} | templateMethod: getImageUrlObject : this">

Peki bizler bu oluşturduğumuz TemplateMethodPipe‘ı ne zaman kullanmayı tercih etmeliyiz?
Aslında bu sorunun cevabı oldukça aşikar… Eğer ki iş mantığı component metodunda yer alıyorsa, bir iş için tek seferlik kullanılacak bir pipe oluşturulması gerekiyorsa ve context ile birlikte bir dönüşüm isteniyorsa bu yaklaşımı kullanabilirsiniz. Yok eğer iş mantığı açısından yeniden kullanılabilir (reusable) ve stateless bir mantıkta çalışma sergilenecekse tabi ki de bu şekilde component bağlayıcı bir yaklaşımın tercih edilmemesi en doğrusu olacaktır.

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

Not : Örnek çalışmaya aşağıdaki GitHub adresinden erişebilirsiniz.
https://github.com/gncyyldz/Angular_Template_Method_Pipe_Example

Bunlar da hoşunuza gidebilir...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir