Angular: Decoratorler ile DOM sorgulama

Tahir KARDAK
6 min readNov 29, 2021

--

DOM; Document Object Model’in kısaltmasıdır. Sayfanın mantıksal yapısı ve sayfanın içerine ulaşıp, değiştirme işlemleri DOM element kullanılarak yapılır. Diğer taraftan, DOM; Javascriptin içerdiği sayfa verilerini görme şeklidir. Tarayıcının durumunu ve HTML/XHTML/XML’nin nasıl biçimlendirildiğini içeren bir nesnedir ve Tüm Html elementleri için eventler, metodları, özellikleri nesne olarak tanımlar.

DOM Queries

Angular, component/ directive içindeki farklı refereans tipleri için iki yol sunar.

  • ViewChild/ViewChildren
  • ContentChild/ContentChildren

DOM sorgulama yapmak için bu decoratorleri nasıl kullanabileceğimize bakalım.

ViewChild/ViewChildren Nedir?

@ViewChild decoratorü, Dom ağacındaki bir tane DOM nesnesinin referansını sorgulamak için kullanılırken, @ViewChildren decoratorü ise sorgu listesi olarak bir referans listesi döndürmek için kullanılır. (ViewChildren'ni @ olmadan kullandıktan sonra)

ViewChild

Aşağıdaki kod ViewChild decoratörünün söz dizilimini gösterilmiştir.

https://gist.github.com/DilinaHirantha/49e0edc04d16ee6b857a93f91ee18fa3#file-viewchild-syntax

Yukarıdaki söz diziliminden de görüldüğü gibi 3 tane ana parametresi mevcuttur.

  • selector: Sorgulanacak elementin belirtecidir ve bir string, tip(type) veya dönüş tipi string veya type olan bir fonksiyon olabilir.
  • read: Bu verilen seçeneklerden biridir. Sorgulanan elementtenn farklı bir token okumak için kullanılır.
  • static: Sorgunun ne zaman çözüleneceği tanımlar. Sayfa görünümü ilk kez başladığında true , Change detection’dan sonra tetiklenmesini istiyorsanız false.

Eğer nesneye onInit’te erişmek istenilirse static:true set edilmeli aksi durumda false set edilmeli. Angular 9 ve sonrasında static sadece true set edileceği zaman kullanılır false için herhangi bir bildirim yapmaya gerek yok.

Şimdi ViewChild kullanım örneğine geçiyoruz.

Bunun için, childcomponent isminde yeni bir component yaratıyoruz.

Aşağıdaki kod childcomponent component şablonuna aittir.

https://gist.github.com/DilinaHirantha/795f06c5c330f19b84d33bcf21c5e2c3#file-template-childcomponent

childcomponent componentini, App Component’in içerisinde child olarak kullandık. Bu nendenle, Ana component’ten gelecek değeri yazdırabilmek için child componente @Input decoratorünu kullanarak birtane input değişkeni tanımladık.

https://gist.github.com/DilinaHirantha/a794bdea4f7e5471a5f00d65992fd306#file-child-component

Daha sonra, bazı ayarları yapmak için app component’e geçiyoruz. Burada app.component.html’de child component’e ait olan selector’u kullandık.

https://gist.github.com/DilinaHirantha/19e45853daa7c21c81885321776e731e#file-app-component-html

componentName isminde özelliği olan başka bir component selector’ünü kullanığımızı ilk görüşte fark edebilirsiniz. Ana component’en child component’e ulaşabilmek için bu özelliği kullanıyoruz.

https://gist.github.com/DilinaHirantha/d6a5c2de384278824998364dda1fe91c#file-app-component-ts

Angular 9+ sonrası kullanım için tıklayınız. static eğer false olacaksa kullanmaya gerek yok.

demo değişkenini kullanarak childcomponent’e ait bilgilere doğrudan ulaşabilirsiniz.

Burada AfterViewInit yaşam döngüsündeki kullanımından dolayı şüpheniz olduğunu düşünüyorum. Child component, uygulama yüklenene kadar tam olarak yüklenmemiş olabilir. Eğer bu durumda child component’e ulaşmaya çalışırsanız, undefined dönecektir. Bu yüzden uygulama tam olarak yüklendikten sonra AfterViewInit’i Angular çağırdığı için kullanıyoruz.

Ayrıca child component’e ulaşmak için ViewChild’ı aşağıdaki gibi kullanabiliriz.

https://enlear.academy/querying-the-dom-in-angular-using-decorators-fd3041bd4497

Burada button element’ine ulaşmak için Html elementini dönen ElementRef kullanabiliriz. Nesne’ye ana componentt’en şu şekilde erişilebilir.

https://gist.github.com/DilinaHirantha/6634d75d1e2bec97b42ef2306c50cd71#file-app-component-ts-new

Bu kısım ve aşağıdaki örnek makalede yok. Başka örnekler vermek istedim. Örneğin ViewChild’a parametre olarak component veya directive verilerek DOM’da değişiklikler yapılabilir. Klasik bir örnek olacak ama örneğin sayaç işlemi yapılabilir. Butonlar aracığı ile sayacın değeri artırılabilir veya azaltılabilir. Ekrandaki butona bastıkça ilgili elementin rengi değiştirilebilir.

Component kullanımına örnek:

Directive kullanımına örnek:

ViewChildren

ViewChild ve ViewChildren arasındaki fark; ViewChildren bir Query liste referansı dönmektedir.

Aşağıdaki örnekte demochild componet’inde nasıl kullanıldığı gösterilmektedir.

https://gist.github.com/DilinaHirantha/bca1178e212cc8f7d3e60f41bc8b5308#file-demochild-component-html

demochild compenent ise;

https://gist.github.com/DilinaHirantha/3f779e4e6cfd159bbb714a16a45387b8#file-demochild-component-ts

Bir sonraki adımda ana component olan app componet şu şekilde olacak.

https://gist.github.com/DilinaHirantha/d7911c72b958a1bbd223c16e99a7ff9a#file-app-component-html-new-2

Buna bakarak child componentlere ulaşmak için name özelliğini 3 kere kullandığımız hemen anlayabilirsiniz. Öyleyse child componentlere bu referanslar aracılığı ile erişebilmemiz gerekiyor.

https://gist.github.com/DilinaHirantha/b5ba1eb5316434e86b80031f92693e9c#file-app-component-ts-new2

toArray metodunu kullanarak bu listeyi diziye çevirebilir bu sayede QueryList’deki child değişkenlere daha iyi görselleştirme için erişebilirsiniz.

Bu kısım ve aşağıdaki örnek makalede yok. Başka örnekler vermek istedim. ViewChildren’a parametre olarak Component, Directive , ElementRef, template referance ve read meta datası verilebilir.

Örnek:

ContentChild/ContentChildren Nedir?

Hem ContentChild hem de ContentChildren ; ViewChild ve ViewChildren ile benzerlik göstermektedir ama aralarında bir fark bulunmaktadır.

“ViewChild veya ViewChildren; Her hangi DOM elementine, Componente veya Directive erişebilir ama projected contentte erişemezler. Öte yandan ContentChild veya ContentChildren projected content’te erişebilirken ancak başka herhangi bir içeriğe erişmek için kullanılmazlar.”

  • Burada projected content; Ana component’ten child componente HTML içeriği geçmenin bir yoludur ve child component, belirlenen bir noktada bu şablonu gösterecektir. Child componentte atamnış noktada(yerde) şabolonu göstermek için ng-content elementini kullanırız. Ayrıca ng-content bu selector’u birden çok kullanarak farklı alanlar oluşturmamıza olanak sağlar. Böylece Ana component bu alanlara farklı içerikler gönderebilir.

ContentChild

Aşağıdaki söz dizilimi bize ContentChild’in, ViewChild’in söz dizilimine benzediğini göstermektedir.

https://gist.github.com/DilinaHirantha/2dbe17c6687cc00595d813aaf947ea56#file-contentchild-syntax

Daha anlaşılır olmak için örneğe geçelim.

İlk olarak, Child component olarak kullanıcak olan bir card componenti yaratıp ve bu componenti kullanarak tek bir card yaratıyoruz.

https://gist.github.com/DilinaHirantha/52e3dbad86a590a86c293b6ed58ba4d9#file-card-component

Card component’te; Ayrı ayrı olarak ng-content kullandık. Bir sonraki adımda, header selector’ünü kullanarak header card component’ine HTML içeriği geçeceğiz. İstediğiniz herhangi HTML içeriğini diğer card component’lerine de geçebilirsiniz.

Bunun için, card list component’ini ana component olarak kullanıyoruz.

https://gist.github.com/DilinaHirantha/0a8df8a03d1f512d0b0bf47debf2e78f#file-cardlist-component

Eğer dikkatlice bakarsanız, h tag’inin içince header property’sini kullarak header’a ulaştığımızı görebilirsiniz.

Bir sonraki adımda card component’e dönüyoruz ve ContentChild’i kullarak güncelliyoruz.

İlk olarak @angular/core'dan ContentChild’ı import ediyoruz.

https://gist.github.com/DilinaHirantha/bb7dfd4569945cfe2fdf7752291fc150#file-import

Daha sonra card component’e aşağıdaki kod parçacığını ekliyoruz.

https://gist.github.com/DilinaHirantha/94de7fb939d034c0957a76a783616719#file-access-header

Burada, headerContent bir değişken. ContentChild decorator’ünü bu değişkene uyguluyoruz. header okumak istediğimiz şablon değişkenidir.h tag’ine uygulandığından bize ElementRef dönecektir.

Ayrıca AfterContentInit lifescycle hook’unu kullanıyoruz. headerContent AfterContentInit hook’ından sonra kullanılabilir durumda olacaktır. Son olarak renderor2 header elementinin stilini değiştirmek için kullandık.

ContentChildren

ContentChildren, ContentChild ile benzerdir ama bize her zaman elementlerin referansını içeren bir liste dönecektir. Eğer birden çok element varsa ContentChild bize ilk karşılaştığı elementi dönecektir.

Bu kısım ve aşağıdaki örnek makalede yok. ContentChildren’a parametre olarak Component, Directive , ElementRef, template referance ve read meta datası verilebilir.

--

--