19 Kasım 2014 Çarşamba

AngularJS - Factory, Service ve Provider

Tıpkı benim gibi AngularJS'e yeni başlayanlar için belki de en çok kafa karışıklığına neden olan konulardan birisi; Factory, Service ve Provider'dir. Bunların tam olarak ne işe yaradığı, hangi durumlarda ve nasıl kullanıldığı, kısıtlamaları vs. oldukça karışık görünür. Anladığım kadarıyla burada toparlamaya çalışacağım.
AngularJS'de sayfa yenilendiğinde veya yönlendirme yapıldığında controller'ların içeriği silinir. Bu nedenle, uygulama genelinde kullanılacak nesnelere erişimi mümkün kılmak için Service'ler kullanılır. Angular'da Service oluşturulması ve kaydedilmesi 3 yolla gerçekleştirilebilir.

1. Factory
Syntax: module.factory( 'factoryName', functionName );
factoryName'i injectable argument olarak tanımladığımız zaman, functionName parametresine ait referansın çağırımındaki değer geri döndürülür.
2. Service
Syntax: module.service( 'serviceName', functionName );
serviceName'i injectable argument olarak tanımladığımız zaman, functionName parametresine ait bir instance geri döndürülür. new functionName() diyebiliriz.
3. Provider
Syntax: module.provider( 'providerName', functionName );
providerName'i injectable argument olarak tanımladığımız zaman, functionName parametresine ait referansın $get methodunun çağırımındaki değer geri döndürülür.
Provider, Service ve Factory'e göre daha karışık görünmesine rağmen onlardan çok daha fazla avantajı vardır. Uygulama henüz başlamadığında, module configuration yapıldığı esnâda Provider'lar kullanılabilir. Aslında Angular Provider'ı tanımakta, Factory ve Service ise Provider'ı sadece miras almaktadır.

Aşağıda bu konuda basit bir örnek bulunmaktadır. Ben .js kodu üzerinde duracağım. Örneğe buradan erişebilir ve kod üzerinde çalışabilirsiniz.

Yukarıdaki örnekte ilk olarak MyFunc isminde bir constructor fonksiyonu tanımlanıyor. Öntanımlı olarak fonksiyon içerisinde name değişkenine 'Factory' atanıyor. $get fonksiyonunda ise 'Provider' atanıyor. Constructor fonksiyonuna ve $get fonksiyonuna girişte console'a log yazdırılıyor. Aşağıdaki ekran görüntüsünden de görüleceği üzere; Provider kullanımında, constructor çağırımından sonra çağırılan $get() fonksiyonunda işlem yapılıyor. Yukarıda bahsettiğim gibi; bu fonksiyon configuration safhasında çağırıldığı için sadece Provider kullanımında bu log basılıyor.
Daha sonra myService, myFactory ve myProvider isminde service, factory ve provider oluşturuluyor.
myModule.controller('myController', [ '$scope', 'myService', 'myFactory', 'myProvider', function($scope, myService, myFactory, myProvider)... kullanımında ise; service, factory ve provider myController oluşturulurken inject ediliyor.

Not: Şu ana kadar paylaştığım Angular uygulamaların tamamına da buradan erişebilirsiniz.

Referanslar

13 Kasım 2014 Perşembe

AngularJS Bootcamp

VNGRS'in düzenlediği AngularJS Bootcamp etkinliği, 22-23 Kasım'da YTÜ Beşiktaş Yerleşkesi, Oditoryum'da yapılacaktır. AngularJS meraklısı iseniz; tam 2 gün boyunca, temelden ileri seviyeye kadar pek çok eğitimin verileceği bu etkinliği kaçırmamanızı öneririm.
Katılmayı düşünürseniz etkinlik sayfasından ücretsiz kaydınızı gerçekleştirebilirsiniz.

AngularJS - $http.get(*.json) parsing error

Harici bir Json dosyasını $scope verisi olarak olarak kullanmak istediğinizde; Developer Console'da SyntaxError: Unexpected token e at Object.parse (native) şeklinde bir hata alıyorsanız, bunun sebebi Json içeriğinin Angular'ın parse edebileceği şekilde düzenlenmemiş olmamasıdır.

Hata görüntüsü aşağıdaki gibidir:


Hatalı Json içeriğinin aşağıdaki şekilde olduğunu varsayalım:
 teams = [ {
"name": "Barcelona",
"country": "Spain",
"teamUrl": "http://tr.wikipedia.org/wiki/FC_Barcelona",
"flagUrl": "http://cd1.dibujos.net/dibujos/pintados/201237/escudo-del-f.c.-barcelona-deportes-escudos-de-futbol-pintado-por-martinb-9769813.jpg",
fanCount: 36619000
}];
Hatanın olası sebepleri şunlardır:

  1. Object dizisi bir değişkene atanmamalıdır. Yani teams = ... olmamalıdır.
  2. Object attribute isimleri ve değerleri " arasına alınmalıdır. Yani fanCount: 36619000 yerine "fanCount": "36619000" olmalıdır.
  3. Dizi tanımlamasından sonra ; kullanılmamalıdır.
Yukarıdaki hatalı json içeriğinin düzeltilmiş hâli şu şekildedir:
 [{
"name": "Barcelona",
"country": "Spain",
"teamUrl": "http://tr.wikipedia.org/wiki/FC_Barcelona",
"flagUrl": "http://cd1.dibujos.net/dibujos/pintados/201237/escudo-del-f.c.-barcelona-deportes-escudos-de-futbol-pintado-por-martinb-9769813.jpg",
"fanCount": "36619000"
}]

12 Kasım 2014 Çarşamba

AngularJS - Filters

Bu yazıda, Angular'da sıkça kullanılan filtreleme bileşenlerinden bahsedeceğim. Bununla birlikte, Angular directive'leri içerisinde expression kullanımı ve harici bir dosyanın da scope verisi olarak kullanımı da örnek uygulamada yer alan konulardır.
Filtreleme bileşeşenleri,verinin istenilen şekilde kullanıcıya görüntülenmesi için kullanılan elemanlardır. Angular'da sıkça kullanılan filter'lara "orderBy" ve "filter"ı örnek verebiliriz. Mevcut filter component listesine ve ayrıntılı açıklamalarına [1]'den göz atabilirsiniz.
Filter'lar ile ilgili örneğe buradan erişebilir ve kod üzerinde çalışabilirsiniz.
Ben daha çok HTML kodu üzerinde duracağım. Ayrıntılı olarak yukarıdaki bağlantıdan göz atabilirsiniz.

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

module1.controller('controller1',function($scope, $http){
 $http.get('teams.json').success(function(data){
  $scope.teams = data;
 });
 
 $scope.sortBy = 'fanCount';
 $scope.reverse = true;
});

Yukarıdaki Javascript kodunda module1 isminde bir module, onun üzerinde controller1 isminde bir controller ve bu controller scope'unda da teams isminde bir değişken oluşturuluyor. teams içeriği ise, teams.json dosyasındaki veri ile dolduruluyor.
Ayrıca sıralamanın neye göre yapılacağını belirten sortBy ve artan/azalan şekilde sıralanacağını belirten reverse isminde değişkenler de $scope'da tanımlanıyor.

<html ng-app="module1">




AngularJS Filters Example


 
Team Flag Country Fans Page
{{team.name}} {{team.country}} {{team.fanCount | number}} Details
</html>
İlk olarak üzerinde durmak istediğim konu: Angular .js'inin kaynağı olarak
cdnjs üzerinde bulunan sürümü kullanılıyor. cdnjs, üzerinde popüler tüm javascript kütüphanelerini barından bir cdn(Content Delivery Network) hizmetidir.
ng-controller="controller1": html'deki bu element'in içerisindeki tüm elementler için, ilgili .js'de oluşturulan controller1 isimli controller'ın kullanılacağı anlamına geliyor.
ng-model="searchText": filtreleme için kullanılacak elementler'den biri olan text field için controller scope'unda bir bir model oluşturuyor. Kısaca bu text field searchText olarak ifade ediliyor ve erişim bu isimle yapılacak.
ng-repeat="team in teams | filter:searchText: gösterilen veriler searchText değerine göre filtrelenerek gösterilecektir.
| orderBy:sortBy:reverse: filtrelenmiş veriler $scope'da tanımlanan sortBy'a göre sıralanacaktır. Bu değerler ilgili .json dosyasındaki object attribute isimleri olabilmektedir. reverse ise orderBy filter'ına gönderilecek ikinci parameterdir(true|false) ve sıralamanın artan veya azalan olduğunu belirtmek için kullanılır.
ng-click="sortBy='name'; reverse=!reverse": burada javascript expression'larının da Angular directive'leri içerisinde kullanılabildiği görülmektedir. İlgili element'e tıklandığında $scope üzerindeki sortBy parameresi set ediliyor ve yukarıda bahsettiğim gibi sıralama bu attribute'a göre yapılıyor. Buna ek olarak; reverse attribute'u bir önceki state'inin tersi şeklinde set ediliyor ve artan/azalan sıralama bu şekilde belirleniyor. Angular expression'lar ile ilgili detaylı bilgiye [2]'den ulaşabilirsiniz.

Referanslar