AngularJS, 2010 yılında Google tarafından duyurulmuş, halen Google ve kendi açık kaynak topluluğu tarafından sürdürülen bir Javascript framework'üdür ve geçtiğimiz sene 2.0 Beta sürümünü kullanıcının beğenisine sunmuştur. Libscore'un verilerine göre 2016 yılında internette en popüler 1 milyon site içerisinden, 10 binden fazla site AngularJS kullanmaktadır. AngularJS istemci üzerinde çalışır, buna göre birçok framework içerisinde sunucu üzerinde yapılan taslak derleme, veri düzenleme, yeniden yönlendirme gibi işlerin hepsi uygulamayı çağıran istemcinin sistemi üzerinde çalışır. Bu da sunucunun daha az işlem yapması sonucunda işlemciye daha hızlı cevap vermesini sağlar. AngularJS bütün HTML dökümanını tek bir nesne olarak görmek yerine içerisinde birden fazla uygulamanın tanımlanmasına ve içerisindeki parçaların farklı denetleyiciler tarafından denetlenmesine izin verir.

AngularJS, özünde MVC (Model-View-Controller) mimari desenine (architectural pattern) benzer MVVM (Model-View-ViewModel) deseni temel alınarak yazılmıştır. Bu desenin MVC'den farkı ise, MVC içerisindeki denetleyicinin (controller) görevi sadece görünüme (view) veri sağlamak iken, MVVM'de model-görünümünün görevi ayrıca görünüme gerektiği zaman çağrılmak üzere farklı fonksiyonlar sağlayarak iki yönlü veri yapısı oluşturulmasına imkan vermesidir. AngularJS model-görünümleri içerisinde de denetleyiciler mevcuttur ancak bunlar MVC desenindeki denetleyici tanımına uymazlar. Buna göre standart bir MVC web uygulamasında kullanıcı model içerisinde bir şeyi değiştirmek istediğinde görünümün güncellenebilmesi için sunucuya yeni bir talep gönderilmesi veya arkaplanda o talebi gönderecek fazladan betik yazılması gerekir; ancak MVVM düzeni ile yazılan kodda görünümün dönüşmesi için verinin aynı değişkene tanımlanması yeterlidir. Model ile model-görünüm arasındaki iletişim genellikle model-görünümün AJAX talepleri veya benzeri bir eşzamansız işlem ile sunucu veritabanından saf veriyi alması ile gerçekleşir. Model-görünüm ve görünüm arasındaki iletişim ise ilişkilendirmeler (bindings) ile çözülür, bunun için ortak bir değişken ismi hem model-görünüm hem de görünüm tarafında ileride değineceğimiz farklı şekillerde bağlanır.

AngularJS'de görünüm, betiğinin çağrıldığı HTML dökümanı içerisine yerleştirilir ve yönergeler (directive) aracılığı ile derlenip, biçimlendirmeler (markup) aracılığı ile veriler model-görünüme bağlanarak gösterilir. Yönergeler çoğunlukla HTML etiketleri olarak veya içerisinde bulunan özniteliklerden (attribute) birisi olarak; AngularJS içerisinde, başka kütüphanelerce tanımlanmış veya geliştirici tarafından özel olarak yazılmış HTML dökümanını değiştiren birimlerdir. AngularJS framework'ünün sağladığı yönergelerden en çok kullanılanlardan bahsedecek olursak: ngApp, AngularJS bulunduğu HTML etiketi içerisindeki içeriği, model-görünüm içerisinde tanımlanmış bir AngularJS uygulamasına bağlar; ngController, bir AngularJS uygulaması içerisinde hangi denetleyicinin uygulandığı HTML etiketi içerisinde çalışması gerektiğini belirtir; ngBind, model-görünüm içerisinde tanımlanmış bir değişkeni HTML etiketinin içeriği ile ilişkilendirir; ngShow, ngHide, ngIf ise içerisindeki değişkenin model-görünümdeki doğruluk değerine göre içeriği gösterir, gizler, oluşturur; ngClick, ngDblclick, ngKeydown vb. HTML içeriğinin içerisinde, isimlerinde belirtilmiş olan Javascript olay tetikçileri çalıştığında model-görünümde çalışacak olan ifadeyi belirtir; ngRepeat,bir dizi içerisindeki değerlerin her biri için verilen değerlere göre taslağı genişletir, diğer dillerdeki foreach döngülerinin karşılığıdır; ngCloak ise uygulandığı kısımda bütün AngularJS derlemeleri çalışana kadar o grubu göstermez, bu AngularJS'in ilk verideki sabitleri algılarken arka-arkaya güncellemesi sonucunda oluşan yanıp-sönme davranışını engellemek için yapılmıştır. Model-görünümde tanımlanmış değişkenlerin değerlerini taslak üzerinde herhangi bir yere yerleştirmek için ise '{{' '}}' etiketleri içerisine değişkenin ismini yazmamız yeterli. Bu etiketler sadece ifade barındırmanın yanında ayrıca temel Javascript ifadeleri ve filtreler de barındırabilmektedir. Buna göre eğer ki model-görünümünüzde a isimli bir sayımız varsa HTML taslağımızın içerisinde herhangi bir yerde {{a+2}} gibi temel aritmetik işlemler, {{“sayi= ”+a}}gibi metinsel işlemler, {{foo(a)}} gibi fonksiyon çağrılarının sonuçları ( foo isimli bir fonksiyonun model-görünüm içerisinde tanımlanmış olduğunu varsayarak) gibi bir çok sonuç elde edilebilir. Ayrıca Angular etiketleri filtrelemeyi de destekler. Filtreler asıl ifadeden sonra | işareti ve fitre adının getirilmesi ile çalıştırılır. AngularJS içerisinde tanımlı bazı temel metin ve sayı dönüştürme filtreleri ile listeler üzerinde temel işlemleri gerçekleştiren bazı filtreler tanımlıdır. Buna göre {{“cclub” | uppercase}} etiketi “cclub” metni üzerinde AngularJS içerisinde tanımlı uppercase (büyük karakter) filtresine göre düzenleyerek “CCLUB” yazısını üretir. Filtrelere parametre de uygulamak mümkündür. Örneğin {{uyeler | orderBy:isim:reverse}} orderBy (-e göre sırala) filtresini isim ve reverse (ters) parametreleriyle çağırır. Bunun sonucunda üyeler isimli dizi her bir elemanının isim özelliğine göre artan sırada sıralanır.

AngularJS'de model-görünüm ise sayfa içerisine yazılan Javascript koduyla veya bağımsız bir Javascript dosyasında tanımlanır. Bu kodun içerisinde bir Angular uygulamasını kontrol etmek için öncelikle uygulamayı ve kullanacağımız diğer kütüphaneleri tanımlamalıyız. Bunun için var foo=angular.module(“Uygulama Adı”,[bağımlılıklar]) yazmamız yeterli. Bunun sonucunda foo isimli değişkene AngularJS uygulamasını aktarmış oluyorsunuz. “Uygulama Adı” kısmını ngApp etiketi ile uygulamayı HTML taslağının neresinde oluşturmak istiyorsak oraya yazmamız gerektiğini daha önce de belirtmiştik. Bağımlılıklar olarak gösterdiğimiz dizinin de içerisine uygulamanın AngularJS çekirdeği içerisinde yer almayan bazı eklerini veya AngularJS'den bağımsız başka kütüphaneleri de eklemek için kullanabiliriz. Bir uygulamayı tanımladıktan sonra onun denetleyicilerini yaratmak için ise app.controller(“Denetleyici Adı”,function($scope){}) yazmak gereklidir. Burada “Denetleyici Adı”, HTML içerisinde belirttiğimiz denetleyici adı; $scope, denetleyici içerisinde kullandığımız değişkenleri barındıran bir nesnedir. Oluşturduğumuz bu fonksiyonun içerisine bütün denetleyici içeriğimizi yazabiliriz, tek dikkat etmemiz gereken şey görünüm içerisinde tanımladığımız değişkenlerin $scope nesnesi üzerinden erişimi olduğu.

Angular içerisinde denetleyicilere farklı özellikler katmaya yarayan bazı hizmetler (service) bulunur. Bunları kullanmak için denetleyici fonksiyonunun içerisine isimlerini yazmak yeterlidir. Aslında $scope bir AngularJS hizmetidir. AngularJS'in sağladığı başka hizmetler de vardır. Bunlar Javascript ile çokça kullanılan işlevlerin AngularJS denetleyicileri içerisinde kullanılabilmesi için geliştirilmiştir. Bunlardan bazılarından bahsetmemiz gerekirse; $http sunuculara kolayca AJAX istekleri gönderme ve dönüt mekanizmaları, $interval ve $timeout Javascript içerisindeki setInterval ve setTimeout fonksiyonlarını genişletip farklı denetleyiciler tarafından zamanlanmış fonksiyonların durdurulabilmesi gibi özellikleri, $compile,$interpolate ve $parse AngularJS'in bir görünümü derlerken kullandığı fonksiyonları, $document ve $window ise tarayıcı tarafından Javascript motoruna sağlanmış document ve window nesnelerini içerir. Bir örnek verecek olursak

var app=angular.module(“DenemeModulu”,[]);
app.controller(“Deneme”,function($scope,$http){
    $http.get(“http://e-bergi.com/”).then(function(cevap){
        $scope.site=cevap.data;
    });
    $scope.site=”Yükleniyor!!”;
});

kodu e-bergi sitesine talep gönderir e-bergi sitesinin içeriğini taslağımızdaki site değişkenine kaydeder, yükleninceye kadar da sitenin yüklendiğini belirtir. Farkedilebileceği üzere AngularJS içerisinde asıl kütüphane ile birlikte gelmiş araçların hepsinin isminin başında $ bulunur.

Angular içerisinde bulunan bir çok hizmet farklı şekillerde çalışmak üzere ayarlanabilir. Bunlar için hizmetlere sağlayıcılar (provider) tanımlanabilir. Bunlar app.config(function(sağlayıcı ,sağlayıcı){}) şeklinde kullanılır. Bir örnek vermemiz gerekirse, diyelim ki biz standart olan {{ }} etiketlerini kullanmak istemiyoruz ve bunları değiştirmeye ihtiyacımız var. AngularJS kendisi de taslakları derlemek için tanımlanmış hizmetleri kullanır. Buna göre $interpolate hizmetini yeniden ayarlayarak istediğimiz sonucu alabiliriz ve bunun için AngularJS içerisinde $interpolateProvider mevcuttur:

var app=angular.module(“DenemeModulu”,[]);
app.config(function($interpolateProvider){
    $interpolateProvider.startSymbol(“_|”).endSymbol(“|_”);
}

yazarak standart taslak etiketleri | ve | yapılabilir.

AngularJS, framework altyapısı haricinde Javascript'te bulunmayan ancak kullanıcıların kullanabilmesi için geliştirilmiş bazı yardımcı fonksiyonları ve jqLite isimli küçük bir jQuery eklentisini de bünyesinde barındırır. Yardımcı fonksiyonlar veri türlerini belirlemek, JSON dönüşümü yapmak ve fonksiyonel programlamayı kolaylaştırmak gibi temel işlevleri gerçekleştirirler. jqLite ise AngularJS üzerinden HTML belgelerinin farklı yapılarına erişebilmek için kullanılır; element fonksiyonu, $document ve $window hizmetleri jqLite nesneleri döndürür. İstendiği taktirde jQuery veya benzeri bir kütüphane de eklenip, ng-jq yönergesi içerisine kütüphaneyi çalıştırmak için gerekli komut (mesela “jQuery” veya “$”) girilerek, o kütüphane de çalıştırılabilir.

Filtreler, yönergeler, hizmetler ve sağlayıcılar model-görünüm ve görünümü tanımlarken kullanılan temel yapıtaşlarını oluşuturur ve kullanıcılar da kendi kullanımları için bunların yenilerini tanımlayabilir, hatta bunları kütüphaneleştirip başka insanlarla da paylaşabilir. AngularJS için yazılan kütüphanelerin içerisinde de aslında yeni bileşenlerden başka bir şeye çok rastlanmaz.

Bu yazımda size AngularJS'i tanıtmaya ve temel özelliklerini anlatmaya çalıştım. Başka bir yazıda görüşmek üzere...