6 Ocak 2014 Pazartesi

AngularJS , Nedir , Nasıl , Nerede , Hangi Durumlarda Kullanılmalıdır ? Yararları ve Zararları Nelerdir ?

AngularJS.. Ne yalan söyleyeyim adamlar Javascript üzerinde MVC(Model-View-Controller) mimariyi tabiri câizse "resmen öttürmüşler".

Tabi kendi resmi internet sitesine (ki buraya tıklayarak gidebilirsiniz) bakacak olursanız, onların tabiriyle bu çatı bir MVC değil MVW mimari...

Açıklamalara göre "W" burada "Model-View-Whatever Works For You" yi temsil ediyor yani "Model-View-Hangisi İşinize Gelirse".Tabi burada kastedilen şey bu framework'u bir MVC mimarisi olduğu kadar isterseniz bir MVVM(Model-View-ViewModel) ya da MVP(Model-View-Presenter) mimarisi olarak da kullanabilirsiniz. Orası size kalmış.

Ve kendim kullandığımdan söylemiyorum, doğru kullanıldığında gerçekten çok hızlı ve stabil kod yazmanızı sağlayabilecek, eğlenceli bir framework.
Ancak tabi dikkatli kullanıldığında ! (ne demek istediğimi az sonra açıklayacağım )

Tabi kullanıp-kullanmayacağımızı,işimize yarayıp-yaramayacağını öğrenmek için öncelikle ne olduğunu öğrenmek lazım.

Angular.JS Nedir ?

Daha deminde anlattığım gibi AngularJS, MVW mimarisine sahip bir Javascript framework'tür.

  • Genellikle SPA(Single-Page Applications/Tek-Sayfa Uygulamalar) tabanlı uygulamalar için kullanılır(ancak tabi diğer uygulamalar için de kullanılmasında bir sakınca yoktur).
  • Browser-Based(tarayıcı-ağırlıklı) uygulamalar için uygundur.
  • Dinamiktir(data binding vs. anlamında)
Nasıl kullanılır ?

Kullanımı oldukça basittir.Öncelikle kütüphaneyi buradan veya angularjs.org adresinden çekin. Daha sonra HTML dosyanıza 
<script type="text/javascript" src="angular.min.js"></script> şeklinde ekleyin. Daha sonra da kodunuzu yazmaya başlayın :) (geleceğiz oralara da)

AngularJS her ne kadar javascript ile yazılmış olsa da biraz kendine özel bir framework'tür diyebiliriz. Dosyayı refere ettikten sonra ilk önce bir ng-app yani AngularJS applikasyonu yazmanız gerekmektedir. Gözünüz korkmasın ama gayet basit ; 

** Bu örneklere resmi internet sitelerinden de ulaşabilirsiniz ancak ben de arada belirtmiş olayım

ilk önce bir javascript dosyası oluşturup içerisine applikasyonumuzu yazalım.

örneğin ; mainapp.js

şablon şu şekilde ilerler ;
ilk önce AngularJS içerisinde bulunan angular namespace'inin altında built-in gelen "module" methodunu kullanarak modülünüzü yazarız ki bizim senaryomuzda appIsmi.

var appIsmi = angular.module('appIsmi',[]);


// daha sonra bu modüle bir controller oluştururuz ;

appIsmi.controller('Kontrolum',function($scope){
//bu kısımda da verimizi elle yazacağız örnek 
$scope.liste = [ {'isim' : 'Microsoft' } , { 'isim' : 'Google'} ];
});


Şimdi burada hemen değinmem gereken bir iki nokta var. 

  1. $scope nedir ? $scope nesnesi, model,control,view arasında iletişim sağlayan objedir. Tüm model-view-controller nesneleri birbirlerinden ayrı olmalarına rağmen onları bir senkronizasyon içerisinde tutar. Yani mesela model üzerinde yaptığınız değişiklik anında bir view üzerine aktarılıyorsa (ki denediğinizde göreceksiniz, zaten AngularJS böyle çalışıyor) bunu sağlayan $scope nesnesidir. 
  2. var appIsmi = angular.module('appIsmi',[]); kısmındaki [] kısmı. Buraya normalde AngularJS üzerine ekstradan eklemek istediğimiz bir modülün ismini gireriz. Örneğin ;  var appIsmi = angular.module('appIsmi',['ngSanitize']); // sanitizasyon(bir çeşit kod temizleme, angular bunu html üzerinde kullanır)
  3. appIsmi.controller('Kontrolum' kısmı ; controller nesneleri birer variable olarak değil bu şekilde string olarak belirtilirler. ( Aslında daha farklı yöntemleri de bulunmaktadır )
Mainapp.js dosyamızı hazırladır. Sonra ?

Şimdi sıra HTML'de. Sihrin oluştuğu yer. 

Öncelikle HTML üzerinde applikasyonumuzu tabiri caizse tanıtmamız gerekmektedir. Bunu da bizim basit örneğimizden devam ettirecek olursak ;


<html ng-app="appIsmi">

şeklinde yapıyoruz.
Geriye de sadece "view" kısmı kalıyor. Oraya da şöyle basitçe değinmek istiyorum. Örneğin elimizdeki verilerin listesini yapalım.Ve bunlara ekleme yapan bir input yapalım.

<div ng-controller="Kontrolum">

    ng-repeat döngüsüyle elimizdeki verileri yazdıralım(bu metod ve nesneleri daha sonraki makalelerimde eğer zamanın olursa açıklamaya çalışacağım)

   <ul ng-repeat="nes in liste">
      <li>{{nes.isim}}</nes>
   </ul>

   <input type="text" ng-model="eklenecek">
   <button ng-click="ekle()">Ekle</button>

</div>

Burada önemli bazı noktalar bulunmaktadır.
  1. "ng-" attribute'leri. AngularJS içerisinde gelirler ve view üzerinde kontrol sağlamamızı sağlarlar. ng yazdıktan sonra yazacağınız kısım işlevinize göre değişir. Örneğin biz burada ng-app , ng-controller, ng-model ve ng-click kullandık. Zaten tireden sonra gelen kısımdan da az çok anlarsınız neyin ne olduğunu.
  2. {{nes.isim}} kısmı ; şimdi doğal olarak merak ediyorsunuzdur. Bu iki süslü parantez de neyin nesi ? Bu parantezler angular ekibi tarafından konulmuştur.  İki süslü ortasına yazılan nesne her zaman bir expression(ifade) olmalıdır. Şöyle bir örnekte verebiliriz {{ nes.isim == "Microsoft" ? "Evet" : "Hayır" }} . Tek bir süslü kullanımında genelde dynamic expression'lar devreye girer. Örneğin bizim modelimizde $scope.liste dizisinin içerisinde şöyle bir durum söz konusu olsaydı ; { "isim" : "Microsoft" , "silindi" : true } biz bunu html içerisinde css class'ları belirlemek için kullanabilirdik. Mesela <li ng-class="{silik : silindi}"> buradaki "silik" css class'ımızın ismi iken "silindi" bize dinamik olarak değer döndürecek değişken. Bu expression sayesinde angular "microsoft" içerikli nesneyi yazdırırken "class='silik'" diye yazdıracaktır çünkü "silindi" nin değeri true 'dur.
  3. ng-click="ekle()" kısmı. Buradaki ekle() metodunu eğer kalkıpta javascript içerisine normal bir metod olarak yazarsanız çalışmayacaktır.Buradaki metoduda mecburen controller altında belirtmeniz gerekir. Ha, aklınız karışmasın, eğer "onclick" yazmış olsaydık normalde nasıl kullanıyorsak öyle kullanmaya devam edebilirdik. Ancak, eğer ng-click kullanıyorsak az sonra göreceğimiz örnekteki gibi metod belirlemiz gerekmektedir.
Şimdi mainapp.js üzerinde birkaç değişiklik yapmamız gerekiyor ;
    appIsmi.controller('Kontrolum',function($scope){
        $scope.liste = [{"isim":"Microsoft","aktif":true},{"isim":"Google","aktif":true},{"isim":"Apple","aktif":false}];
        $scope.eklenecek = "";
            $scope.ekle = function(){
                $scope.liste.push({"isim":$scope.eklenecek,"aktif":false});
            }
        });

Son olarak test ettiğinizde göreceksiniz ki, kodumuz çalışmaktadır. Şimdi teknik kısmı atladıktan sonra gelelim diğer önemli konulara....
Nerede ve hangi durumlarda kullanılır/kullanılmalıdır ?
Aslında bu soruya en iyi cevabı siz vereceksiniz tabi, ben sadece kararı almanızda yardımcı olmaya çalışacağım.

Projenizin türü nedir ?
Eğer projeniz bir back-end projesi veya hiçbir arama motorunda çıkmaya ihtiyaç duymayan bir projeyse devam edin. Muhtemelen çok akıllıca bir seçim olacaktır. Ancak eğer front-end bir proje üzerinde çalışıyorsanız(ya da front-end i siz yazıyorsanız) ve eğer SEF ve SEO sizin için çok önemliyse açıkçası çok da tavsiye etmem.
Çünkü dikkat ederseniz direkt olarak HTML kaynak  kodlarının arasına data-binding yapıyoruz. Her ne kadar biz bunu dinamik bir kaynağa bağlamış olsak dahi, arama motorunun botu bu verileri okuyamayacaktır... mı ? Tam olarak hayır.
Burada tabi hemen Google'ın Ajax Crawling sistemine değinmek lazım. Eğer daha önce Ajax Crawling yapmışsak biliyoruzdur ki, SEO ve SEF açısından bu mevzu tam bir baş belası olabilir. Ancak Google'ın getirdiği bazı düzenlemeleri ile HTML Snapshot taktiği kullanılarak indeksleme'de verinin düzgün bir biçimde anlaşılması sağlanabilir.
Ama bu demek değildir ki avantajlısınız. Bir kere, Html Snapshot için ya ekstra kod yazacaksınız ya da 3. parti kütüphaneler ( PhantomJS vs. ) kullanarak bunu sağlayacaksınız. Bu bana göre büyük bir dert. Ancak eğer bunu göze alabilirseniz tabi ki AngularJS yine iyi bir çözüm.
Ancak eğer bir back-end projesi yapıyorsanız, hele bir de SPA olarak tasarladıysanız...AngularJS tam sizin için.
Neden diyeceksiniz, burada da artık "Yararlar ve Zararları" kısmını açıklamanın zamanı geldi...

Yararlar
  1. Direktifler yazabilirsiniz ; şöyle ki :

        <slayt adi="falan"></slayt>
        ya da
        <div bizim-slayt></div>
    
Custom(İsteğe Özel) HTML tagları veya attribute'lar aracılığı ile "User Control" nesneleri... Bunun bize ne kadar büyük kolaylıklar getirebileceğini hepimiz tahmin edebiliriz.

  • ng-repeat 'in sağladığı kolaylıkla kod kalabalığından kurturuluz. Bir nesneyi birden fazla kez tekrar edeceksek bunu ufak bir template yazarak halledebiliriz.
  • Çok karmaşık değildir. Biraz üzerinde durduğunuzda çok kısa sürede çözersiniz.
  • RESTFul aksiyonlar standart haline getirilmiş ve AngularJS'e entegre edilmiştir.
  • MVVM sayesinde, model üzerindeki değişiklik anında view üzerine yansır.
  • Unit-Testing için idealdir.
  • $routeProvider nesnesi sayesinde (özellikle SPA için) harika bir routing sistemi kurabilirsiniz. AngularJS kendi içerisinde bunu bir-iki modülle yapabilmektedir.
  • Takım projelerinde, iş paylaşımı yapılabilmesini sağlar.
  • En önemlisi ... Google tarafından geliştirildiği için stabilite bakımından çokta bir endişeniz olamaz :)


  • Zararlar
    1. (Üstü çizili çünkü tam olarak bir sorun sayılmaz)Direktiflerin IE8 uyumluğu bir sorun olabilir.Ancak AngularJS üzerinde yayınlanan bir makalede bu aşılmıştır.
    2. Bahsettiğimiz SEO ve SEF biraz sıkıntılı olabilir.

    Gördüğünüz gibi tam olarak bir zarardan/sıkıntıdan da bahsedemiyoruz. En azından ben daha çok büyük bir sıkıntıyla karşılaşmadım. Umarım biraz olsun yardımcı olabilmişimdir. Edindiğim bilgileri, vaktim oldukça paylaşmaya devam edeceğim.
    Sağlıcakla.

    Hiç yorum yok:

    Yorum Gönder