Angular 2 & 4 Template Syntax / Data Interpolations – Dinamik veri bağlama ve html yönetimi

Bu yazıda Angular içinde bir çok kavrama biraz daha aşina olabilmek ve genel olarak bütün “yeni nesil” front-end framework  lerinde 3 aşağı 5 yukarı aynı olan , “Template Syntax  / Data Interpolations”  konusuna bakmaya çalışacağız.

Angular” ile html ve html içinde kullanacağımız dinamik veya statik verilerimizi yönetmek” diyebileceğimiz  bu konu genel itibariyle tüm Javascript freameworklerinde az çok bulunan ortak bir yapı.

Angular 2 Template Syntax  / Data Interpolations

En sade haliyle “Javascript içindeki her türlü verimizi html içerisinde kolayca kullanmamıza olanak sağlayan alt yapı. ” diyebiliriz. İlk olarak Angular uygulamamızda, kullancağımız html yapımızı componentlerimize dahil etme şeklimize bakalım. Angular bize 2 alternatif yol sunmakta; Inline html kullanımı yada external html linki ile html i dahili etme.

1 – Inline or External Templates / Dahili yada harici html kullanımı

Inline / Dahili html yapısı :

Componentlerimiz içinde dahili olarak tanımlayabileceğimiz html yapsını, Componentlerimiz içersinde ki, “@Component” dekaratörü için deki “template” alanı ile kullanıyoruz.

@Component({
selector: 'okunmamis-mesajlar',
template: `
   <h1>Örnek</h1>
   <h2>{{okunmamisMesajSayisi}} Okunmamış mesaj</h2>
  `
})
export class OkunMamisMesajCmp {
  okunmamisMesajSayisi: number =12;
}

@Component” dekaratörü için de, dahili html kullanımı genelde küçük html yapısı olan componentlerimiz için ideal. Böylece componentimizin ihtiyacı olan her şey tek parça olarak bir dosya halinde tutulabilmiş oluyor.

Yukarıda, Typescript/ES6 özelliği olan : ` ` (back tick / ters tırnak) içerisinde multi-line/çok satırlı html yazmamıza imkan vermekte. Normal tek yada çift tırnak kullanarak da(‘ ‘ , ” “) html i yazabilsekde, back-tick/ters tirnak ile birden fazla ile  daha kolay yazma imkanımız mevcut.

External/ Harici html yapısı :

html kodlarımızı yukarıdaki gibi, component içinde değil başka bir html dosyasında tutup, o dosyanın linkini kullanarak html component e dahil edebileceğimiz yapı. component içinde çok fazla html kodu bulundurmak yerine, html yapısını component içerisinden çıkartmak için “template” özelliği yerine “templateUrl” i kullanıyoruz.

@Component({
selector:'okunmamis-mesajlar',
templateUrl:"./mesajlar.html"
})
export class OkunMamisMesajCmp {
  okunmamisMesajSayisi: number = 12;
}

 Interpolation

Angular 1 deki benzer yapı “{{ degisken_yada_javascript_ifadesi }}” angular 2 de biraz daha geliştirilmiş ve zone kavramı ile daha hızlı bir rendering imkanı verilmiş. Component içinde tanımladığımız değişkenleri yada metodları html yapımız içinde kullanmamıza imkan veren bu yapıya örnekle bakalım.

@Component({
 selector: 'kullanici-sayisi',
  template:`
   <h1>Toplam Kullanıcı : <strong>{{kullaniciSayisi}} </h1>
   <h2>Online Kullanıcılar {{onlineKullaniciSayisi}}</h2>
  `
})
export class KullaniciSayisi{
kullaniciSayisi: number= 1200;
  onlineKullaniciSayisi: number = 75;
}

Angular 1 ile arasındaki en temel fark, TypeScript sayesinde tip desteğimiz,  bir de çalışma zamanında eğer  kullaniciSayisi değişkeni tanımlanmadan kullanılmaya çalışılırsa, Angular  nin bize hata mesajı vermesi.(daha önce undefined değerler için her hangi bir hata almıyorduk).  Örneğin ;

<h2>Online Kullanıcılar {{kullaniciSayisi.online}}</h2> // kullanıcı sayısı değişkeni bir online değere yada metoda sahip değil.

Angular 2 ile birlikte aşağıdakine benzer bir hata almamız söz konusu.

Cannot read property 'online' of undefined in [{{kullaniciSayisi.online }} in KullaniciSayisi]

Kısacası angular  javascript in doğal yapısını biraz daha kontrol altında tutmakda ve daha kolay hata yakalama ayıklama imkanı sunmakta.

Safe Navigation Operator  – “?”

C# kullandıysanız,  nullable operatör kavrama benzetebileceğiniz ve angular a biraz daha esneklik göstermesini söyleyebileceğiniz yeni bir operatör “?”. örneğin yukarıda kullanıcıSayisi isimli değişkene değeri sunucudan gelcek bir cevaba göre atayacağımızı düşünün,  Yukarıdaki örneği şu şekilde yazabiliriz ;

<h2>Online Kullanıcılar {{kullaniciSayisi?.online}}</h2> 
// kullanıcı sayısı değişkeni online isimli bir alana sahip olmasada artık hata mesajı almayacağız.

Kısacası, Asenkron işlemler için kullanışlı bir yöntem, Angular işaretini gördüğünde, eğer değişkenimiz bir değer taşımıyorsa hata mesajı vermek yerine bu değerin ileride elde edilebileceğini yada isteğe bağlı değer taşıyabileceği durumlar için uyarılmış oluyor böylece hata yönetimini kolaylaştımış oluyoruz.

Property binding

Dinamik veri bağlama ve html yönetimi için Interpolation angular  tarafından sunulan ve ençok kullanacağımız yapı. Fakat Angular 2 ile Property binding dedigimiz ve html atribute larını kullanarak da html yapısı içinde dinamik veri erişimini sağlayabilmekteyiz.

Uygulamalarımızda [ ] köşeli parantez içinde html attribute şeklinde kullanabileceğimiz bu yapı ilk başta biraz karışık yada garip gözüksede çok ciddi esneklik ve kullanım kolaylığı sağlamakta. Angular 1 içinde kullandığımız bir çok directive i angular  dan kaldıran bu yapıya bakarak devam edelim.

<input type="text" value="osman">

Yukarıdaki html kodu ile içinde osman yazan bir textbox ı sayafaya yazdırmış oluyoruz. Bu html elementinin type ve value  isimli iki tane attribute özelliği var. Bu 2 attribute html içinde textbox için standart attribute ler yani bizim eklediğimiz tanımladığımız attribute değiller.

Yukarıdaki kullanımı angular aracılığıyla dinamik hale getirmek için yapmamız gerekn tek şey ilgili attribute u  [ ] köşeli parantez içine almak,

<input type="text" [value]="osmanDegiskeni">

Artık osmanDegiskenin taşıdığı değer dinamik olarak, textBox a taşınacak.

Normal de , html(DOM) içinde olan fakat kullanmadığımız bir çok attribute da söz konusu, örneğin “textContent”  gibi. Aşağıdaki örnekle devam edelim;

<p> {{onlineKullanciSayisi}} </p>

yukarıdaki kullanımla aşağıdaki kullanımlar temelde aynı. Yukarıdaki kullanım daha kısa ve kolay versiyonumuz

<p [textContent]="onlineKullanciSayisi"></p>
<p textContent="{{onlineKullanciSayisi}}"></p>

yukarida, textContent değişkenini [ ] içine alarak angular a dinamik bir atama yapacağımızı, ve onlineKullanciSayisi değişkeninin değişmesi halinde p tag i içindeki değeride güncellemesini söylemiş oluyoruz. Veya diğer kullanım şekliyle [ ] kullanmadan textContent in değerini dinamik hale getirip( {{onlineKullanciSayisi}} ) aynı işlemi yapmış oluyoruz.

Asıl esneklik bu yapının aşağıdaki örneklerde gösterildiği gibi bir kullanımıyla gelmekte. Örneğin bir elemnti dinamik olarak gizleyip göstermek için kullanabileceğimiz ve angular 1 deki ng-if yada ng-hide/show yapısına alternatif olarak kullanabileceğimiz aşağıdaki örneğe bakalım;

<div [hidden]="gizlimi">Gizli text</div>

hidden attribute u DOM yapısı içinde standart bir attribute, hidden değeri gizlimi isimli bir değişkenle dinamik olarak takip edilmekte ve böylece, ng-hide/show gibi bir yapıya gerek kalmadan, HTML in kendi yapısı içinde bu div elementini gizleyip gösterebilmekteyiz. Bu haliyle, doğal HTML/DOM attribute larını kullandığımız için ng-if yada ng-hide gibi yapılara göre çok daha hızlı bir rendering elde etmiş olmaktayız.

Çünkü angular her hangi bir şeyi yeniden sayfaya yazdırmak yada kaldırmak yerine, sadece bir attribute değişmiş olacak ve tarayıcımız otomatik olarak ilgili işlemi yerine getirecek.

Aşağıdaki diğer örnekle devam edelim;

<div [hidden]="gizlimi" [style.color]="arkaPlanRengi">Gizli ve renkli text</div>

Yukarıda, hidden attribute ile birlikte bir de style ı kullandık. Normalde style attribute u kullanım şeklimiz  style=”color: #00A000″ bu şekildeyken, angular  bize nested attribute / iç içe geçmiş şekilde attribute tanımlama imkanı da vermekte. [style.color] gibi.

Componentimiz içinde dinamik olarak yönetebileceğimiz iki değişkenimiz (gizlimi ve arkaPlanRengi) ile div elementimizin rengini ve görünürlüğünü kolayca yönetebiliriz.

herhangi bir değer atanamayan, sadece tanımlanmalarıyla çalışan attribute larımızda var, örneğin selected yada disabled gibi. Bu attribute lara bir değer atamanız normalde bir anlam ifade etmez yani aşağıdaki iki kullanımda textbox u disabled/kullanılamaz halde tutacaktır.

<input type="text" name="soyad" disabled>
<input type="text" name="soyad" disabled="false">

bir html elemtinin içinde “disabled” attribute olduğu sürece kullanılamaz halde olacatır, “disabled” a bir değer atamanız bir önemi yoktur.

Angular iki ile bu tarz attribute ları dinamik olarak yönetmek için de […] yapısını  kullanabiliriz;

<input type="text" name="soyad" [disabled]="kullanilabilirmi">

Böylece kullanilabilirmi isimli değişken, true değeri taşıdığı sürece textbox disabled  olacaktır. Başka bir kullanım kolaylığıda, Angular   ile hem attribute yönetimi, hem de  ayni sekilde alt componentlerimize verilerimizi gectimiz yapı “ayni API ı /alt yapıyı” tasimakda.

Böylece, standart tek bir yapı ile hem html elementlerimizi kolayca yönetebilme imkanı hemde componentlerimize dinamik yada statik veri aktarımı daha kolay hale gelmekte. Bu konu Componentlerle ilgili kısımda anlatıldığı için oraya bırakıyorum.

Angular 2 Events – Event tanımlama

Angular 1 deki event tanımlama için geliştirilmiş dahili direktifleri hatırlayalım;

ng-click, ng-keyup, ng-mousemove vs...

Artık bu tarz direktiflere gerek duymadan aşağıdaki ne benzer bir sentaks ile event tanımlama yapabilmekteyiz.

<button (click)="hesapla()"> Hesapla</button>

En temel fark ise artık, javascript ile gelen tüm event tanımlamalarını olduğu gibi kullanacak olmamız. Artık click event  için ng-click kullanıma gerek olmaması gibi. Yapmamız gereken tek şey; (click) event ismini parantez içine almak ve değer olarak componentimizdeki ilgili metodu atamak.

<button (click)="hesapla($event)"> Hesapla</button>

$event isimli değişken angular  tarafından, çalışma zamanında otomatik olarak bizim için erişilebilir olacaktır. Component içinde kullanmak için $event değişkenini parametre olarak gecmeniz yeterli olacaktır. örneğin;

hesapla(event) {
  event.preventDefault();
  event.stopPropagation();
}

şeklinde kullanabilmekteyiz. Angular  ile tüm standart javascript eventlerini kullanabileceğimiz gibi, kendi oluşturduğumuz event leri de takip etme imkanımız var. Bu konu Componentler yazısında ele alındığı için oraya bakabilirsiniz. Bir  başka yeni ve güzel özellik de , tıpkı attribute nesting gibi event nesting imkanımızın da olması.

Örneğin kullanıcın space/boşluk  tuşuna basması halinde bir işlem yapmak istediğimizde aşağıdaki kod yerine ;

document.body.onkeyup=function(e){
    if(e.keyCode==32){
        //space tuşuna basıldı, bişeyler yap
    } }

angular  ile şu şekilde kolay bir kullanımı gerçekleştirebiliriz;

<textarea (keyup.space)="SpaceTusunaBasildi()"></textarea>

Bu yapıyı dahada ileri götürüp daha karışık kombolar elde edebiliriz; keydown.alt.space gibi.

Local variables – Yerel Değişkenler

Angular 2 ile birlikte yeni gelen ve benim de çok beğendiğim özelliklerden biri olan “local vars / yerel değişkenler” bir çok ihiyacımızı kolayca karşılama için tasarlanmışlar. Öncelikle, yerel değişkenlerimizim tanımlandıkları html template seviyesinde bir etki alanları olduğu nu belirtelim. Sonrasında da nasıl tanımladıklarına bakalım. İhtiyacımız olan tek şey , ilgili html elementi içinde # işaretiyle  elementi temsil edecek bir local/yerel değişken tanımlamak

<input type="text" #isim>

Yukarıda, input elementinin tamamını referans edecek “isim” adında bir değişken tanımladık. Html elementinin tamamını referans edecek dedik çünkü Angular 2 (tıpkı, Jquery gibi) html elementinin kendisini seçme imkanı sunmakta. Hem bir değer,  hem de elementin kendisine bir referans tutmuş  oluyoruz. Böylece Angular 2 içinde ki Observables gibi diğer alt yapılarla çok daha rahat çalışma imkanımız da oluyor.

Tüm lokal değişkenler temsil ettikleri html elementinin yapısına göre bir değer/value taşımaktalar . böylece textbox un taşıdığı değer “isim.value” şeklinde erişilebilmekte.

Bu kolay erişim sayesinde, uygulamamız içinde daha az sayıda 2 way data binding yada dinamik değişken takibi yapma imkanına sahip olmuş oluyoruz. Performans açısından Angular 2 ile gelen kazanımlardan biride bu tür kullanım imkanları.

Kısacası yukarıda ne textbox,  nede taşıdığı değer dinamik olarak sürekli takip edilmemekte. Böylece , sadece ihtiyacımız olduğunda Jquery dekine benzer bir şekilde isim.value şeklinde bir erişim imkanı sunmakda.

Local Variables/ Yerel değişkenlerin bize sağladığı bir diğer kolaylıkda, yukarıda bahsettiğimiz “html elementinin kendisine” bir referans taşıması ve elementin üzerinde direkt olarak HTML/DOM api larını kullanım imkanı vermesi . Daha iyi anlaşılması açısından şu örneğe bakalım;

<input type="text" name="name" #isim/>
<button (click)="isim.focus()"></button>

Yukarıda, click event e dikkat edersek, #isim değişkenimizin focus() metodunu çağırmakta. isim değişkeni bir text input olduğu için bir focus() metodu var, bizde elimizdeki bu referans ile bu html elementinin kendi metodlarınıda bu şekilde kolayca kullanabilmekteyiz. Özellikle, jquery benzeri 3. parti kütüphanaler ve eklentilerle çalışırken işimizi kolaylaştıracak bir başka özellik.

Örneğin, bir video eklentimiz/componentimiz olduğu düşünün,

<video-player #video></video-player>
<button (click)="video.play()"> Baslat</button>

benzeri bir kullanımı gerçekleştirebiliriz. Local değişkenler çok kullanışlı ve dinamik veriler için değil  daha çok html elementi üzerinde kolayca işlemler yapabilmemiz yada componentlerimizi daha temiz tutabilmek içinde de tercih edebileceğimiz çok güzel bir yenilik Angular 2 içinde.

Canonical syntax – Kaçış yada alternatif Sentaks

Bazen sunucu tarafında kullandığımız, template sistemi, istemci tarafında kullandığımız yapıyla aynı söz dizimini kullanabilir. Yada başka bir sebebten, farklı bir söz dizimine ihtiyaç duyabiliriz. Angular 2 için de bu alternatifler i aşağıda görebiliriz.

Yukarıda önceki hali #video olan yerel değişkeni alternatif olarak let-video şeklinde tanımlayabiliriz ornegin. Local değişkenimizin kullanımında ise her hangi bir değişiklik söz konusu değil.  Yine aynı şekilde event ler için ; (click) yerine on-click kullanabilmekteyiz.  Son olarak köşeli parantez yerine bind- kullanabilmekteyiz.  Örneğin;

<video bind-name="video.name"></video>

gibi . Bu örnekle birlikte, let– , bind- ve on- ön eklerinin angular 2 dünyasında özel bir anlamı olduğunu aklımızda tutmayıda unutmayalım . Kısacası, eğer bir sebebten “standart ” söz dizimini kullanamama gibi bir durum olursa, kaçış sentakslarını kullanabilme imkanımız var.

*  işareti ve structural directives/ yapısal direktifler.

Angular 2 içinde ” * ” işaretiyle başlayan direktifler dikkatinizi çekmiştir. Bunlar Angular  ile dahili olarak gelen direktifler.  Örneğin ;

*ngIf  yada *ngFor

Angular 2 web component standartlarını takip ettiği için normalde yukarıdaki yapıları ilk başlarda; şu şekilde bir tanımlama ile kullanıma sunmuş;

<ng-template [ngIf]="videos.length > 0">
  <div><h2>Vi{{Videos.length}}</h2></div>
</ng-template>

Gördüğümüz gibi, orjinalinde template şeklinde ve [ ] ile attribute yapısını kullanan bu yapı biraz uzun ve bazı durumlarda karmaşık olabileceği için, Angular 2 takımı bize kullanım kolaylığı sağlamak adına ” * ” lı bir  alternatif sunmakta. Kısa ve kolay bir alternatif olan bu yöntem ile yukarıdaki template ifadesini şu şekilde yazabilmekteyiz;

<div *ngIf="videos.length > 0"><h2>{{videos.lentgh}}</h2></div>

Başka bir değişle, angular 2 web component standartlarını takip etmeye çalıştığı için, orjinalinde yukarıdaki template yapısını kullanmakta, yıldız ” * ” lı versiyonlar ise sadece template sentaksına bir kısa yol alternatifi.  2 yöntemide angular 2 içinde kullanabilme imkanımız var ama genel olarak hep “yıldızlı *” versiyonu kullanmak daha kolay.

Son olarak aşağıdaki liste ile yazıyı bitirelim.

  • {{}} for interpolation / Javascript veri veya metodların html içine yansıtılması
  • [] for property binding / html özellikleriyle bağlama
  • () for event binding / olay bağlama
  • # for variable declaration / yerel değişken tanımı
  • * for structural directives / yapısal direktifler

Bir sonraki yazıda görüşmek ümidiyle. Kolay Gelsin.

 

 

 

 

 

2 thoughts on “Angular 2 & 4 Template Syntax / Data Interpolations – Dinamik veri bağlama ve html yönetimi

Leave a Reply

Your email address will not be published. Required fields are marked *