Angular: İrtibatı koparmayalım!

0 3.051

Angular’da proje geliştirirken componentler arası bilgi paylaşımı yapılması kaçınılmaz bir durumdur. Bir componentte bulunan bilginin başka bir componentte aktarılması veya bir componentte tetiklenen bir olayın başka bir componentten yakalanması gibi iletişim durumları söz konusu olabilir. Örnek verecek olursak; “Kitap” diye bir componentimiz olsun. Bu component yüklenirken servisten(backend) ilgili kitaba ait; adı, açıklama, yorum ve puan bilgileri gelsin. “Kitap” componentimizin içerisinde kullanıcıların yapmış olduğu oylamaların gösterildiği, yeni bir oylamanın yapıldığı “Oylar” componenti ve yorumların listelendiği “Yorumlar” componenti olsun. Kitap (parent) componentinde var olan oylama bilgisini Oylar (Child) componentine, kitap hakkında yapılmış yorumları Yorumlar(Child) componentine aktarılması gerekebilir. Bu işlemi yapabilmek için pratik çözüm her bir componentin ihtiyaç duyduğu bilgileri servisten tekrardan çekmek olabilir. Böyle bir durumda uygulamamız pek performanslı olmayacaktır. Bizi bu tarz bir durumdan kurtarmak için; @Input ve @Output decoratorleri sahneye çıkıp, bu işlemleri kolay bir şekilde yapmamıza olanak veriyor.

Bu makalede Angular’da componentler arası iletişim/bilgi paylaşımı için yaygın olarak kullanılan @Input ve @Output decoratorlerinden bahsedeceğim. Tahmin edebileceğiniz gibi componentler arası iletişim farklı şekillerde de yapılabilmektedir. Bir sonraki makalem bu paylaşım şekilleri hakkında olacak. Yukarıda verdiğim örneği makale boyunca geliştirmesini yaparken, bir yandan da decoratorler hakkında açıklama yapacağım. Makale bitiminde projenin github linkini paylaşacağım.

İçindekiler:
Bu Makalede aşağıdaki konuları içerecektir
* Proje Senaryosu
* @Input ve @Output decoratorleri nedir, ne işe yarar?
* Örnek Proje
* Sonuç
* Kaynaklar
* Proje Kodları (Github Repository)

Senaryo:

Örnek senaryomuz şu şekilde olacak. Kullanıcı ekranda kitap bilgilerini görebilecek. Kitap hakkında yapılmış yorumları okuyup yeni yorum yapabilecek. Kitap için verilmiş puanlamayı görüp kendi puanlamasını yapabilecek. Book componenti bizim parent componentimiz olacak, diğer componentler ise child componentlerimiz olacak.

Projemizin Taslağı

Veri/Bilgi Değiş Tokuşunu yapan bir araç

Basitce özetlersek @Input ve @Output decoratörlerine, componantler arası veri ve bilgi alış verişini yapan araçlar diyebiliriz. Bu iki decoratorun çalışma mekanızması bir componentten bilgi almak veya bilgi göndermek şeklindedir.

@Input: Componentler arası bilgi alma işlemini yapar. Yani parent componentteki bir bilginin, child componente aktarılması için kullanılır. (Parent → Child)

@Output: Child componentteki bir bilgiyi, parent componente aktarmak için aktarmak için kullanılan decoratordur. Bu aktarım genellikle “EventEmitter” ile yapılır. Yani parent componentte bulunan bir method @Output ile child componentten tetiklenerek bilgi aktarımı sağlanır. (Child →Parent)

Aşağıdaki çizimde bu durumu açıklamaya çalıştım. Detaylı bilgi için Angular dokümantasyon linkini makalenin sonunda bulabilirsiniz

Haydi mutfağa!

Yukarıda anlattıklarımı daha iyi anlamak için kod yazmak en iyi yöntemdir. O yüzden mutfağa girip işe koyuluyoruz.

Projemizin iş akışını yukarıda belirtmiştim. Şimdi projemizi yaratıp çalışma tezgahımızı hazırlayalım.

İşe öncelikle Angular CLI kullanarak yeni bir proje oluşturmakla başlıyoruz.

Bilgisayarınızda Visual Studio Code ve node.js yüklü olmalı. Eğer yüklü değilse Visual Studio Code için burayı, Node.js için burayı tıklayın

Visual Studio Codeyi açtıktan sonra terminale aşağıdaki kodu yazarak yeni projemizi yaratıyoruz

Projemde bootstrap kullandım. Bootstrap işlemleri için burayı tıklayınız. Ayrıca makalede template sayfalarında kullandığım css işlemleri hakkında bilgi vermeceğim, konumuz @Input ve @Output decoratorleri. Ama css kodların tamamı github linkinde olacaktır. Oradan bakıp sizde uygulayabilirsiniz.

Componentleri yaratıyoruz:

Aşağıdaki komutları terminal’de sırası ile çalıştırıyoruz.

İşlemin sonunda proje yapımız şu şekilde olacaktır.

Proje yapısı

book.component.ts” parent componentini açıp kitap bilgilerini hazırlıyoruz. Bu bilgileri herhangi bir servisten almıyoruz. Konumuz @Input ve @Output. Başka bir makalede bu konu hakkında detaylı bir şekilde bahsedeceğim.

Kitap nesnesinde şu bilgiler olacak:

adi, aciklama: Bu iki değişken “book.component.ts” ve “book.component.html” dosyalarında kullanılacak herhangi bir child componentte kullanılmayacak

puan, kisiSayisi: Bu iki değişken “rate.component.ts” ye aktarılıp “rate.component.html” ve“rate.component.ts” de kullanılacak.

puanDetay: Kitap puanlarının tutulduğu listedir(Array). Bu bilgi “rate-result.component.ts” ye aktarılıp “rate-result.component.html” de kullanılacak.

yorumlar: Bu değişken “comments.component.ts” ye aktarılıp “comments.component.html” de kullanılacak.

Ayrıca “book.component.ts” da kullanıcıların yorum yapmasını sağlayacak ve bu bilgiyi “comments.component.ts” ye aktaracak yorumEkle()metodunu ekliyoruz. Yine aynı dosyada kullanıcının kitabı puanlayıp bilgiyi “rate-result.component.ts” ye aktaracak puanla(puan: number) metodunu ekliyoruz.

rate.component.ts” child componentini açıp. @Input ve @OutPut olacak değişkenleri tanımlıyoruz.

toplamPuan: Kitap hakkında şu ana kadar yapılmış puanların tutulduğu değişkendir. Bu değişken bilgisi parent componentten gelecek. Bu değişken bizim input değişkenimiz olacak. Değişkeni tanımlarken değişkenin başına @Input() ekleyeceğiz.

kisiSayisi: Kitabı oylayan toplam kişi sayısı için tanımlanan değişken. Bu değişken bilgisi parent componentten gelecek. Bu değişken bizim input değişkenimiz olacak. Değişkeni tanımlarken değişkenin başına @Input() ekleyeceğiz.

puanDegistir: Kullanıcının oy vermesini sağlayacak değişkendir. Bu bilgi ile kullanıcının puan bilgisi alınacak, parent componente aktarılacak. Bu değişken bizim output değişkenimiz olacak. Değişkeni tanımlarken değişkenin başına @Output() ekleyeceğiz. Output değişkeni “EventEmitter<>()” şeklinde tanımlanır. Eğer bu değişkenin örneğin sayısal parametre alacaksa “EventEmitter<number>()” şeklinde tanımlanır

 

Paylaşmak Güzel Şeydir. Bilgileri paylaşıyoruz. Paylaştıkça Mutlu oluyoruz.

Şimdi “book.component.ts” de tanımladığımız bilgileri “rate.component.ts” ye aktarıyoruz. bu işlemi yapmak için “book.component.html” dosyasını açıyoruz. Aşağıdaki işlemleri yapıyoruz

 

Componentler arası bilgi aktarımı

Türkan Şoray Kanunları!

Parent “Html” dosyasında işlem yaparken dikkat edilmesi gereken kurallar şu şekildedir:

  • Parent componentten, child componente aktarılacak değişken eşitliğin sağ tarafına yazılır. Değişken isimler parent componentte yazılan isimle aynı olmak zorunda.

  • Parent componentten gelen bilgiyi karşılayacak child componente ait değişken bilgisi eşitliğin sol tarafına yazılır. child componentte belirtilen isimle aynı olmak zorunda.

  • Input değişkenler “[]” içine yazılır örneğin: [değişken_adi]

  • Output değişkenler “()” içine yazılır örneğin: (değişken_adi)

Bilgileri Kullanıyoruz:

@Input: book.component.ts” den gelen bilgileri “rate.component.html” de aşağıdaki şekilde kullanıyoruz.

{{toplamPuan}} ve {{kisiSayisi}} şeklinde html dosyasına yazıp kullanıcıya bilgileri kullanıcıya gösteriyoruz

@Output: Kullanıcı oy kullanmak için “rate.component.html” de bulunan 5 puan veren yıldıza bastığında oyVer(5) methodu “rate.component.ts” de tetiklenip output değişkeni ile verilen puanı ayarlayıp, parent componentimize (“book.component.ts”)bu bilgiyi gönderiyor.

Bu işlemin sonunda “book.component.ts” dosyasında bulunan puanlametodu tetiklenerek child componentten gelen bilgiyi kullanıp gerekli işlemleri yapacak.

Diğer Child componentlerde de benzer işlemleri yapıyoruz. Uzun makalenin okunmama riski olduğundan diğer işlemlere ait kodları github linkinde paylaşacağım.

Sonuç:

Projemizi çalıştırıyoruz. Terminale aşağıdaki kodu yazıyoruz

Makalenin kaynak kodları: https://github.com/thrkrdk/ng-input-output

@Input ve @Output için Angular dokümanı: https://angular.io/guide/component-interaction#component-interaction

Email adresiniz yayınlanmayacaktır.