30 Kasım 2015 Pazartesi

Angular JS ' ye Giriş

Merhabalar bugün Angular JS hakkında bildiklerimi paylaşmak istiyorum.  Angular JS ye başlangıcım araştırma ve ufak bir proje vesilesi ile gerçekleşti. İyi ki araştırma yapmışım böylesine muazzam bir konu hakkında bilgimin olmaması ve getirmiş olduğu kolaylıkların farkında olmamak kötü bir his uyandırırdı.  Angular JS, basit tabirle google standartlarına uygun ve desteklediği, javascript tabanlı bir MVC kütüphanesidir. MVC (Modal View Controller) verideki , görünümün ve kontrollerinin farklı tutulmasına dayanır.
Html etiketlerine (tag) çeşitli özellikler (attribute) ekleyerek, Html’i genişleterek hızlı bir şekilde ve kolayca dinamik web aplikasyonları oluşturmamızı sağlar
Angular JS çalışmak için jQuery gibi kütüphanelere ihtiyaç duymamıza gerek yoktur. Karmaşıklık yok denilebilecek kadar az olup az kod ile çok iş yapmakta mümkündür ki bana göre en güzel tarafı budur yani çift taraflı çalışması (two way binding). Mesela bir inputtaki değeri değiştirdiğinizde anlık olarak belirlenmiş olan span içeriğindeki veride değişir .
Angular JS yaklaşık 100KB dır ve resmi sitesi https://angularjs.org/ dır.
Kod yapısında  <head> tagları arasına
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
Scripti eklendiği takdirde Angular JS yi indirmeden direk sitesindeki kütüphaneyide kullanabilirsiniz.
Angular JS çeşitli bileşenleri içeren modüller halinde düzenlenmiştir. Bu bileşenler Direktifler (directives), hizmetler (services), sağlayıcılar (providers), Tipler (types), genel apiler dir.

Angular kütüphaneleri.
ng : angularJS nin temel modüllerini içerir. Bir angularJS uygulaması başlatıldığında bu modül varsayılan olarak yüklenir.
ngRoute : Uygulamada url yönetimi yapılmasını sağlamak için kullanılır. (angular-route.js)
ngAnimate: Uygulamada animasyon özellikleri için kullanılır. (angular-animate.js)
ngResource : Rest api veri yönetimi için kullanılır. (angular-resource.js)
ngCookies: Cookie yönetimini sağlar. (angular-cookies.js)
ngTouch: Mobil tarayıcılar için geliştirilen uygulamalarda kullanılır. (angular-touch.js)
ngSanitize: HTML verilerini güvenli bir şekilde ayrıştırmak ve işlemek için kullanılır. (angular-sanitize.js)
ngMock: Test modülleri için kullanılır. (angular-mock.js)

Ayrıca Angular, hiç js kodu yazmadan, template kısmında koşullu ifadeler ve deyimlerle çalışma olanağı sağlar ki işin en güzel tarafı budur diyebiliriz . Şimdi yavaştan örneklerimize geçelim. Örneklerimiz ile  Neden Angular JS  ?
Sorusuna cevabı kendiniz vereceksiniz.


Uygulama-1: İlk uygulamamız bir text içerisindeki yazıyı span içerisine uygulamak olsun.
İlk olarak html bir sayfa oluşturalım ve head kısmında angularJS kütüphanesini sayfamıza tanımlayalım.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>

<html> olarak oluşan sayfamızda Angular JS uygulamasını kullanabilmek için  
<html> tagları arasına ng-app  ekleyerek <html ng-app>  yapıyoruz. Buradaki amaç kodların bir nevi Angular JS ile taranması demek oluyor. Sonra input tanımlayarak ng-model ile bir değişken adı tanımlayalım.
ng-model  directive scope’unuzda bir değişken tanımlanızı sağlar ve bu değişkenin binding’ini ilgili elementin value’usu veya text’i olarak ayarlar. Burada two way binding (çift taraflı bağlama) kurulur.
- {{isminiz}}: çift süslü parantezler arasına scope içerisinde tanımlanan değişkenleri kullanarak bunları ekranda gösterebilir veya çeşitli işlemlere sokabiliriz.
 

Ekranda göründüğü gibi text alanına Dünya yazarak hiçbir  javascript kodu yazmadan anlık “Merhaba Dünya” yazısı yazıldı.
KAYNAK KODLARI
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html ng-app>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<title>Oktay ALTAN - Angular JS</title>
</head>
<body>
 <input type="text" ng-model="isminiz" placeholder="Adınızı Giriniz"> <br/>
<span>Merhaba {{isminiz}}</span>
</body>
</html>
Uygulama-2 : deger adlı değişken; bir, iki ve üç butonlarına tıklandığında sırasıyla birinci,ikinci ve ucuncu değerlerini alıyor. ng-show ile true false kontrolü yapılır. Eger true ise span içerisindeki içerik veya yazılar yazılır.

KAYNAK KODLARI
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html ng-app>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<title>Oktay ALTAN - Angular JS</title>
</head>
<body>
<section ng-app ng-init="deger = 1">
  <h2>Hangi butona basıldığı kontrolü</h2>
  <div>
    <button ng-click="deger = '1'">bir</button>
    <button ng-click="deger = '2'">iki</button>
    <button ng-click="deger = '3'">uc</button>
  </div> 
  <div>
    <span ng-show="deger == '1'">birinci</span>
    <span ng-show="deger == '2'">ikinci</span>
    <span ng-show="deger == '3'">ucuncu</span>   
  </div>
</section>
</body>
</html>

Uygulama-3: Angula JS  ile matematiksel işlemlerin nasıl yapıldığına dair ufak bir uygulama yapalım .
Bu örnekte ng-model ile tanımlamış olduğumuz iki değişkeni <div> ler içerisinde işlemlere tabi tutarak sonuç elde edeceğiz.
ng-init değişken içerisindeki ilk değer anlamına geliyor. 


KAYNAK KODLARI
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html ng-app>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<title>Oktay ALTAN - Angular JS</title>
</head>
<body>
<section ng-app ng-init="sayi_2 = 3; sayi_1 = 25">
  <section>
    <h2>Oktay İle Angular matematiksel işlemler</h2>
    Birinci sayı: <input type="text" ng-model="sayi_1"/>
    İkinci sayı: <input type="text" ng-model="sayi_2"/>
    <hr />  
    <div>
      {{ sayi_1 }} - {{ sayi_2 }} =  {{ sayi_1 - sayi_2 }}
    </div>
    <div>
      {{ sayi_1 }} * {{ sayi_2 }} =  {{ sayi_1 * sayi_2 }}
    </div>
    <div>
      {{ sayi_1 }} / {{ sayi_2 }} =  {{ sayi_1 / sayi_2 }}
    </div>
    <div>
      {{ sayi_1 }} % {{ sayi_2 }} =  {{ sayi_1 % sayi_2 }}
    </div> 
  </section>
</section>
</body>
</html>




Uygulama-4: Bu uygulamamızda 12 sayı verip girilen rakamlara göre filtreleme yapalım. ng-repeat ng-modul e ait bir directive dir. Array içindeki nesnelere sıralı erişim sağlar.


 KAYNAK KODLARI
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html ng-app>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<title>Oktay ALTAN - Angular JS</title></head>
<body>
<section ng-app ng-init="sayilar = [45, 658, 548, 358, 154, 69, 48, 87, 451, 35, 680, 15]">
  <h2>AngularJS ng-repepat ve filter</h2>
  Sayıları içerdiği rakama göre filtreleyin: <input ng-model="rakam" />
  Bulunan öğe sayısı: {{ (sayilar | filter: rakam ).length }}
  <hr />
  <div>
    <span class="oge" ng-repeat="sayi in sayilar | filter: rakam">
      {{sayi}}
    </span>
  </div>
</section>
</section>
</body>
</html>
Uygulama-5: Uygulamamız not ekleme ve silme işlemi yapıyor olsun. Burada not ekleme ve silme adımları için 2 satırlık javascript kodu kodlandık. 



<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
       
        <script type="text/javascript">

            function notcontroller($scope) {
                $scope.notlar = [];

                $scope.notekle = function () {
                    $scope.notlar.push({ ad: $scope.notadi });
                    $scope.notadi = "";
                }

                $scope.notsil = function (ind) {
                    $scope.notlar.splice(ind, 1);
                };
            }

        </script>
    </head>
    <body ng-app>
        <div ng-controller="notcontroller">

            <input type="text" name="not" id="not" ng-model="notadi"/>
            <a href="javascript:void(0);" ng-click="notekle()">Ekle</a>


            <ul ng-repeat="not in notlar">
                <li>{{$index}} - {{not.ad}} <a href="#" ng-click="notsil($index)">sil</a> </li>
            </ul>

        </div>
    </body>
</html>











Uygulama-6: Kisiler listemiz olsun ve bu listeyi ng-repeat ile ekrana yazalım. Filtre için ve order by için de inputlar ekleyelim ve ister ad a göre istersede yaş a göre filtrelere yapıldın.

KAYNAK KODLARI
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>      
        <script type="text/javascript">
          function listecontroller($scope){
    $scope.kisiler = [
      {ad:'Bilge', yas:32, cinsiyet:'K'}
      ,{ad:'Okan', yas:12, cinsiyet:'E'}
      ,{ad:'Ahmet', yas:18, cinsiyet:'E'}
      ,{ad:'Mehmet', yas:25, cinsiyet:'E'}

    ];   
    $scope.order_cols = [{v:'ad',t:"Ad"},{v:'yas',t:"Yaş"},{v:'cinsiyet',t:'Cinsiyet'}];
    $scope.order_types = [{v:true,t:"Azalan"},{v:false,t:'Artan'}];
   
    $scope.order_col=$scope.order_cols[0];
    $scope.order_typ=$scope.order_types[0];
   
    $scope.format = function(k){
        //k.cinsiyet setlenirse kisiler nesnedeki değer güncellenmiş olur.
        if(k.cinsiyet == "E")
            k.cinsiyetformat = "Bay"
        else
            k.cinsiyetformat = "Bayan"
    }
}

        </script>
    </head>
    <body ng-app>
<div ng-app>
    <div ng-controller="listecontroller">
        <input type="ara" ng-model="k.$" placeholder="ara..." />
        <input type="ara" ng-model="k.ad" placeholder="ad..." />
        <input type="ara" ng-model="k.yas" placeholder="yas..." />
       
        <select ng-model="order_col" ng-options="i.t for i in order_cols">
        </select>

        <select ng-model="order_typ" ng-options="i.t for i in order_types">
        </select>
       
        <div ng-repeat="k in kisiler | filter:k | orderBy:order_col.v:order_typ.v"  ng-init="format(k);">
            <div ng-show="$first">Kişiler</div>
            <div class="even{{$even}}">{{$index+1}} -> {{k.ad}} - {{k.yas}} - {{k.cinsiyetformat}}</div>
            <div ng-show="$last">Toplam {{kisiler.length}} kayıt</div>
        </div>
    </div></div>
    </body>
</html>
Uygulama-7: İşin içine birazda CSS karıştırıp Kişi ekleyip silebileceğimiz bir arama uygulaması yapalım.


KAYNAK KODLARI
<!DOCTYPE html>
<html ng-app>
<head>
<script  src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
<link href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script>
function ctrl($scope){
  $scope.rows = ['Ali'];
  $scope.temp = false;
 
  $scope.addRow = function(){
    $scope.temp = false;
    $scope.addName="";
  };
 
  $scope.deleteRow = function(row){
    $scope.rows.splice($scope.rows.indexOf(row),1);
  };
 
  $scope.plural = function (tab){
    return tab.length > 1 ? 's': '';
  };
 
  $scope.addTemp = function(){
    if($scope.temp) $scope.rows.pop();
    else if($scope.addName) $scope.temp = true;
   
    if($scope.addName) $scope.rows.push($scope.addName);
    else $scope.temp = false;
  };
 
  $scope.isTemp = function(i){
    return i==$scope.rows.length-1 && $scope.temp;
  };
 
}
</script>
<meta charset=utf-8 />
<title>Oktay ALTAN - Angular JS</title>
</head>
<style>
body{
  padding:20px;
}
.search{
  margin-left:10px;
}
</style>
<body ng-controller="ctrl">
  <h2>{{rows.length}} Kişi <span ng-show="temp">?<small class="muted"><em > (Şuanda {{rows.length-1}} kişi bulunmakta....)</em></small></span></h2>
  <form class="form-horizontal">
  <span ng-class="{'input-append':addName}">
    <input id="add" type="text" placeholder="Eklenecek Kişiyi yazınız..." ng-model="addName" ng-change="addTemp()"/>
    <input type="submit" class="btn btn-primary" ng-click="addRow()" ng-show="addName" value="+ Ekle"/>
    </span>

    <span class="search input-prepend" ng-class="{'input-append':search}">
      <span class="add-on"><i class="icon-search"></i></span>
  <input type="text" class="span2"  placeholder="Kişi Ara..." ng-model="search">
    <button type="submit" class="btn btn-inverse" ng-click="search=''" ng-show="search" ><i class="icon-remove icon-white"></i></button>
</span>
  </form>
  <table  class="table table-striped">
    <tr ng-repeat="row in rows | filter : search"  ng-class="{'muted':isTemp($index)}">
      <td>{{$index+1}}</td>
      <td>{{row}}</td>
      <td>
        <button class="btn btn-danger btn-mini" ng-click="deleteRow(row)" ng-hide="isTemp($index)"><image src="images.png"/></button>
      </td>
    </tr>
  </table>
 
</body>
</html>



Uygulama-8: Basit bir  Search uygulaması.

KAYNAK KODLARI
<html>
<head>
<meta Charset = "utf-8"/>

<script  src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>

<script>
var app = angular.module("icerikara", []);
app.filter('searchFor', function(){

                return function(arr, searchString){

                               if(!searchString){
                                               return arr;
                               }

                               var result = [];

                               searchString = searchString.toLowerCase();

                               angular.forEach(arr, function(item){

                                               if(item.title.toLowerCase().indexOf(searchString) !== -1){
                                                               result.push(item);
                                               }

                               });

                               return result;
                };

});



function InstantSearchController($scope){


                $scope.items = [
                               {
                                               url: 'http://vodafoninternet.com/',
                                               title: 'Vodafone Çağrı Merkezi',
                                               image: 'http://emrereklamcilik.com/_sn2/module/sa2_resize.aspx?f=/upload/image/logo/_vodafone.jpg&w=100&h=100'
                               },
                               {
                                               url: 'http://www.superonlinenet.net/',
                                               title: 'Turkcell Çağrı Merkezi',
                                               image: 'https://yt3.ggpht.com/-rD0D5bABe0A/AAAAAAAAAAI/AAAAAAAAAAA/CeNphd6R_Ig/s100-c-k-no/photo.jpg'
                               },
                               {
                                               url: 'http://ruyaavcisi.com/',
                                               title: 'Güzel Sanatlar Resim Kursu',
                                               image: 'https://yt3.ggpht.com/-s7xB-bzutE4/AAAAAAAAAAI/AAAAAAAAAAA/c_uYEUbOyQE/s100-c-k-no/photo.jpg'
                               },
                               {
                                               url: 'http://erdemins.com/',
                                               title: 'Erdem İnşaat Sitesi',
                                               image: 'http://www.bedava.biz.tr/css/images/reklam4.png'
                               },
                               {
                                               url: 'http://duvarressami.net/',
                                               title: 'Duvar Ressamı ',
                                               image: 'http://cdn.tutorialzine.com/wp-content/uploads/2013/05/featured-100x100.jpg'
                               },
                              
                ];

}
</script>
<style>
*{
                margin:0;
                padding:0;
}

body{
                font:15px/1.3 'Open Sans', sans-serif;
                color: #5e5b64;
                text-align:center;
}

a, a:visited {
                outline:none;
                color:#389dc1;
}

a:hover{
                text-decoration:none;
}

section, footer, header, aside, nav{
                display: block;
}



.bar{
                background-color:#5c9bb7;

                background-image:-webkit-linear-gradient(top, #5c9bb7, #5392ad);
                background-image:-moz-linear-gradient(top, #5c9bb7, #5392ad);
                background-image:linear-gradient(top, #5c9bb7, #5392ad);

                box-shadow: 0 1px 1px #ccc;
                border-radius: 2px;
                width: 400px;
                padding: 14px;
                margin: 45px auto 20px;
                position:relative;
}

.bar input{
                background:#fff no-repeat 13px 13px;
                background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkU5NEY0RTlFMTA4NzExRTM5RTEzQkFBQzMyRjkyQzVBIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkU5NEY0RTlGMTA4NzExRTM5RTEzQkFBQzMyRjkyQzVBIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RTk0RjRFOUMxMDg3MTFFMzlFMTNCQUFDMzJGOTJDNUEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RTk0RjRFOUQxMDg3MTFFMzlFMTNCQUFDMzJGOTJDNUEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4DjA/RAAABK0lEQVR42pTSQUdEURjG8dOY0TqmPkGmRcqYD9CmzZAWJRHVRIa0iFYtM6uofYaiEW2SRJtEi9YxIklp07ZkWswu0v/wnByve7vm5ee8M+85zz1jbt9Os+WiGkYdYxjCOx5wgFeXUHmtBSzpcCGa+5BJTCjEP+0nKWAT8xqe4ArPGEEVC1hHEbs2oBwdXkM7mj/JLZrad437sCGHOfUtcziutuYu2v8XUFF/4f6vMK/YgAH1HxkBYV60AR31gxkBYd6xAeF3VzMCwvzOBpypX8V4yuFRzX2d2gD/l5yjH4fYQEnzkj4fae5rJulF2sMXVrAsaTWttRFu4Osb+1jEDT71/ZveyhouTch2fINQL9hKefKjuYFfuznXWzXMTabyrvfyIV3M4vhXgAEAUMs7K0J9UJAAAAAASUVORK5CYII=);

                border: none;
                width: 100%;
                line-height: 19px;
                padding: 11px 0;

                border-radius: 2px;
                box-shadow: 0 2px 8px #c4c4c4 inset;
                text-align: left;
                font-size: 14px;
                font-family: inherit;
                color: #738289;
                font-weight: bold;
                outline: none;
                text-indent: 40px;
}

ul{
                list-style: none;
                width: 428px;
                margin: 0 auto;
                text-align: left;
}

ul li{
                border-bottom: 1px solid #ddd;
                padding: 10px;
                overflow: hidden;
}

ul li img{
                width:60px;
                height:60px;
                float:left;
                border:none;
}

ul li p{
                margin-left: 75px;
                font-weight: bold;
                padding-top: 12px;
                color:#6e7a7f;
}
</style>
</head>
<body>
<div ng-app="icerikara" ng-controller="InstantSearchController">

                <div class="bar">
                               <input type="text" ng-model="searchString" placeholder="Yapmış olduğum bazı siteler..." tabindex="1" autofocus/>
                </div>

                <ul>
                               <li ng-repeat="i in items | searchFor:searchString">
                                               <a href="{{i.url}}"><img ng-src="{{i.image}}" /></a>
                                               <p>{{i.title}}</p>
                               </li>
                </ul>
</div>
</body>
</html>