Direktifler Angularjs framework yapısı içerisindeki en önemli kavramlardan biridir. Direktifler HTML attribute ve elementler ile ulaşılabilen yeniden kullanılabilir ve test edilebilir kod blokları oluşturmayı sağlar.
Bu yazının konusu Angularjs direktifleri konusuna giriş niteliğinde olup, direktifler ile ilgili bir yazı dizisinin de başlangıcıdır. Bu yazı dizisinde kendi özel direktiflerimizi oluşturup kullanmayı ve direktiflerin detaylarına değineceğiz. Konu başlıkları genel olarak şu şekilde olacaktır:
- Direktiflerin Tanımlanması
- Direktif Restriction Yapısı
- Scope Ayrımı
- Ayrılmış Scope Tarafına Erişim
- Direktif Kalıtımı (Inheritance)
Özel direktiflerin tanımlanmasına geçmeden önce Angularjs bünyesinde bulunan başlıca direktifleri inceleyelim.
- ng-show: Bir HTML elementinin gösterilmesini sağlar.
- ng-hide: Bir HTML elementinin gizlenmesini sağlar.
- ng-click: Bir HTML elementine tıklandığında çalışacak fonksiyonu gösterir.
- ng-class: Bir HTML elementin class özelliğini belirler.
- ng-style: Bir HTML elementin style özelliğini belirler.
- ng-repeat: Bir HTML elementi tekrarlı bir sırayla yazar.
Örnek kullanım şekilleri:
<button ng-show="isVisible"></button>
<button ng-hide="isSecret"></button>
<button ng-click="sendMessage()"></button>
<button ng-class="big-button"></button>
<utton ng-style="yellow"></button>
<button ng-repeat="item in socials"></button>
Angularjs bünyesindeki bu direktiflerin ihtiyacımızı karşılamadığı durumlarda kendi özel direktiflerimizi oluşturabiliriz. Kendi özel direktiflerimizi oluştururken dikkat etmemiz gereken bazı kurallar vardır. Bu kurallar olmazsa olmaz katı kurallar olmaktan ziyade ilkesel olarak benimsenmiş kurallardır. Örneğin direktiflerin isimlendirilmesi dikkat edilmesi gereken kurallardan biridir.
Direktifleri nasıl isimlendirmeliyiz?
Direktifler isimlendirilirken kullanıcıların okuduklarında kolayca anlayabilecekleri ve birbiri ile çakışmayan benzersiz ön ekler kullanmaya özen gösterilmelidir. Kendi özel direktiflerimizi kullanırken “ng-“ ön ekini kullanmamalıyız. Çünkü “ng-“ angular tarafından belirlenmiş özel bir ön ektir. Bunun yerine iki harf ile belirlediğimiz özel ön ekler kullanmayı tercih edebiliriz.
Direktiflerin javascript tarafındaki isimlendirme şekli Camel Casing şeklinde yapılmaktadır. Örneğin javascript tarafında “mySocialButtons” gibi bir isimlendirme tercih edebiliriz.
angular.module("directives", [])
.directive("mySocialButtons", [function(){..}]
Angularjs HTML tarafından direktife erişirken, bu isimlendirmeyi küçük harfler ve her kelimenin arasına “-” karakteri kullanarak çağırmaya izin verir. Örneğin HTML tarafında “my-social-buttons” şeklinde direktifimizi çağırabiliriz.
<my-social-buttons> </my-social-buttons>
Özel direktifleri ne zaman tercih etmeliyiz?
- Tekrar tekrar kullanılabilir HTMl bileşenleri oluşturmak istediğimiz durumlarda kullanabiliriz.
- Elementlere aynı davranışları vermek istediğimizde kullanabiliriz.
- Bir jQuery plugin ile çalışmak istediğimiz durumda onu paketlemek için kullanabiliriz.
- DOM ile etkileşime geçmek istediğimiz her zaman direktifleri kullanabiliriz. Controller, Service ve Factory gibi bölümlerden DOM elementlerine erişmek kötü bir yöntemdir. Çünkü kodun test edilebilirliğini azaltır ve kodu DOM’a bağımlı hale getirir.
Direktiflerin Tanımlanması
Direktiflerimizi oluşturmadan önce direktiflerin tutulacağı modülleri oluşturmalıyız. Bu ayrımın sebebi direktiflerin ana uygulama modülünden bağımsız ve test edilebilir özellikte olmasıdır. Ana modül içerisinde her şeyin tanımlanması karmaşık bir uygulamanın oluşmasına neden olacaktır. bu nedenle ana uygulamamızın bulunduğu modülü özel direktiflerimizi tanımlamak için kullanmamalıyız. Direktif modülünü uygulama modülüne sonradan yüklemeliyiz.
Örnek uygulamanın konusu, her web sitesinde karşılaştığımız sosyal medya butonlarını tekrar tekrar kullanabilmek için bir direktif haline getirmektir. Görüldüğü üzere ana modül app şeklinde isimlendirilmiştir. Direktifin tanımlanacağı modül directives adlandırılmış ve ana modüle sonradan yüklenmiştir. Eğer ana modül ile ilgili bir direktif oluşturacaksanız app modülüne bağlı bir şekilde tanımlamanızda bir mahsur yoktur.
Direktif fonksiyonu bir nesne döndürmektedir. Bu nesnenin bazı üyeleri vardır. Bu üyeler şu şekildedir:
- restrict
- scope
- template veya templateUrl
- link
- controller
Direktifin restrict üyesi
Bu nesnenin restrict özelliği direktifin tipini belirler. Direktiflerin dört farklı tipi vardır. Bunlar:
- ‘A’ attribute türünde direktifler
- ‘E’ element türünde direktifler
- ‘C’ class türünde direktifler
- ‘M‘ yorum türünde direktifler
Direktifin scope üyesi
Direktifin faaliyet alanını(scope) belirler.Direktifler veri bağlantısını kendi faaliyet alanlarından(scope) alabilecekleri gibi direktif dışındaki bir direktiften veya controller’dan da sağlayabilir.
Direktifin template üyesi
Direktifler DOM üzerine yerleştiklerinde görüntülenmek isteniyorsa HTML tanımlamaları yapılmalıdır. HTML tanımlaması düz metin şeklinde yapılabileceği gibi dışarıdaki bir *.html dosyaya templateUrl ile erişilerek de yapılabilir. Yukarıdaki örnekte templateUrl kullanılmıştır.
Direktifin link üyesi
Direktifin link() fonksiyonu direktifin DOM elementi ile temasa geçtiğinde yani uygulama yüklendiğinde çalışır. DOM içerisinde her direktif örneği (instance) için bir kez çalışır. Bunu test etmek için link() fonksiyonu içerisine console.log(“work”) yazabilirsiniz. Konsola sadece bir kez “work” yazdığını gözlemlyebilirsiniz.
Direktiflerin link() fonksiyonunun parametreleri dependency injection yöntemiyle verilmez. Parametreler belli bir durum sırasına göre(positional) sıralanmıştır. Sıralama scope, attribute, element, controller şeklindedir.
Direktifin controller üyesi
Bir direktif eğer dışarıdan veri almaya ihtiyaç duymuyorsa yani sadece görünüm(view) taraflı bir yaklaşımı varsa bu tür direktifler görünüme dayalı (view oriented) olarak düşünülebilir. Bunlar basit direktiflerdir. Ancak kendi verisini kendi temin edebilen direktifler oluşturmak isteniyorsa ki bu tür direktifler veriye dayalı (data-oriented) direktiflerdir. Bu tür direktiflere controller üyeleri eklenir. Bir controller ile direktifin servisler aracılığı ile dışarıdan kendi verisini alması sağlanabilir. Eğer mantıksal iş kuralları varsa yine controller içerisinde tanımlanabilir.
Eğer bir direktif görünüm tarafı ve kontrol tarafı ile bütünleşik olarak tanımlanmış ise bu tür direktifler component ya da widget diye adlandırılabilir. Direktifleri yazının en başında bahsettiğim kadar önemli kılan şey, ihtiyaç duyduğu bir çok özelliği bünyesinde taşıyabiliyor olmasıdır.
Angularjs 2.0 ve sonrası için direktifler daha da önemli hale gelecek. Çünkü artık tek başına controller yapılarının olmadığı yeni bir sürüm yolda gibi görünüyor.