Can.JS kategorisindeki dördüncü makalemiz, nesnelerin değerleri değiştiği zaman haberimizin olmasını ve otomatik aksiyonlar aldırmamızı sağlayan Observe sınıfı hakkında olacak. Esasen EJS ve View konularını henüz işlemediğimiz için bu konu biraz havada kalabilir. Ancak bu konuları işlemek için de bu sınıfı öğrenmemiz gerekiyor. Bu yüzden, sınıfın kullanım şeklini ve ne işe yaradığını anlatacak örnekler vereceğim. Makaleyi tamamlarken de EJS ve View ile kullanımı hakkında kısa bir örnek vereceğim. Verdiğim örneğin EJS ve View ile ilgili kısımlarını lütfen anlamaya çalışma. Sadece Observe sınıfına odaklanarak ne amaçla kullanıldığını öğrenmen, bu makale için yeterli. EJS ve View konusunda zaten başlı başına bir makale yazacağım.


Kısa bir ön açıklamadan sonra konumuza dönelim. Şimdi anlatacaklarımı hayalinde canlandırmanı istiyorum. SPA şeklinde çalışan yoğun form kontrolleri içeren bir uygulama yazmışız. Ekranda pek çok Tab, bu Tab'larda pek çok Label, TextBox ve benzeri kontroller var. Bunların tamamında, bir yerden alınan veriler yazılı halde duruyor. Sonrasında herhangi bir anda bu veriler değişiyor. Değişiklik yapıldığı anda, ekrandaki tüm kontrollerin de güncel değerleri göstermesini nasıl sağlarız? Bir düşünelim...

Kötü yöntem, ekrandaki tüm kontrolleri doldurmak için ortak bir metot yazarız (Örneğin FillForm). Ardından değerleri değiştiren her bir kod bloğunun altında bu metodu çağırırız. Neden kötü? Çünkü değerleri değiştiren yerler her zaman bizim kontrolümüzde olmayabilir. Örneğin sınıfımızdaki bir değişkenin değerinin dışarıdan değiştirilmesi gibi.

Daha az kötü yöntem, değerler için get/set fonksiyonları yazarız. Böylece değerler değiştiği anda, hatta öncesinde haberimiz olur ve ilgili kontrolün değerini değiştirebiliriz. Neden az kötü? Değişikliğe uğrayacak değer adedince get/set fonksiyonu ve form kontrolünü değiştiren kod yazmak zorundayız.

İşte burada, Observe sınıfı çok güzel bir şekilde bu işin üstesinden geliyor. Nasıl olduğunu sözel olarak anlatmak zor, her zamanki gibi örnekler üzerinden gideceğim.

Dikkat Can.JS'nin 2.1 versiyonu ile birlikte can.Observe sınıfının adı can.Map, can.Observe.List sınıfının adı da can.List olarak değiştirildi. Bu yüzden, "Observe Sınıfı" makalesini tamamlayanlar muhakkak "2.0 ile Gelen Değişiklikler" isimli makaleyi de okusunlar.

Not : Observe sınıfı daha önce gördüğümüz Construct sınıfından türemiştir. Bu sebeple teknik olarak, Construct sınıfının yapabildiği her şeyi yapabilir. Ancak Observe sınıfı farklı bir amaç için yazılmıştır ve kullanılmaktadır.

Benzer şekilde, daha sonradan göreceğimiz Model ve Route sınıfları da Observe sınıfından türemiştir ve teknik olarak Observe sınıfının yapabildiği her şeyi yapabilir. Ancak onlar da farklı birer amaç için yazılmıştır ve kullanılmaktadır.

Hangi sınıfın hangi sınıftan türediğini bilmek, yeteneklerinin farkına varmak için önemlidir ancak sınıfların asıl yazılış sebeplerini anlamak daha da önemlidir.

İlk olarak HTML sayfamızı oluşturalım.

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1254" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="can.jquery-1.1.7.min.js"></script>
<script src="program.js"></script>
</head>
<body>
</body>
</html>


Ardından "program.js" dosyamızı oluşturalım.

"use strict";

$(document).ready(function () {

    var obj = new can.Observe({
        deger1: 1,
        deger2: "Ali"
    });

    obj.attr("deger1", 10);

    $("body").append(obj.attr("deger1"));
    $("body").append("<br>");

    obj.attr({
        deger1: 20,
        deger2: "Veli"
    });

    $("body").append(obj.attr("deger1"));
    $("body").append("<br>");

    $("body").append(obj.attr("deger2"));
    $("body").append("<br>");

});

Bu örneğin hazır yazılmışını çalıştırmak için buraya tıklayabilirsin. Karşına aşağıdaki gibi bir sayfanın gelmesi gerekiyor.


Bu örneği sadece Observe sınıfı ile nesne oluşturma ve değer atama/okuma işlemlerinin nasıl yapıldığını anlatmak için hazırladım. Henüz ekranda dinamik olarak bir hareket görmeyeceğiz. Şimdi adım adım kodu inceleyelim.

    var obj = new can.Observe({
        deger1: 1,
        deger2: "Ali"
    });

Burada Observe sınıfı ile yeni bir nesne tanımladık. bunu sanki "new Object()" ile tanımlamış bir nesne gibi varsayabiliriz. Nesnemizin "deger1" ve "deger2" isimli iki adet özelliği bulunuyor ve bunlara ilk değerlerini atamışız.

    obj.attr("deger1", 10);

Burada nesnemizin "deger1" adlı özelliğine 10 değerini atıyoruz. Dikkat, bu kısım önemli. Observe ile üretilmiş bir nesnenin herhangi bir özelliğini değiştirmek için "attr" fonksiyonunu kullanmak gerekiyor. Fonksiyon ilk parametre olarak özellik adını, ikinci parametre olarak değerini alıyor.

    $("body").append(obj.attr("deger1"));

Burada da, nesnemizin "deger1" adlı özelliğinin değerini ekrana yazdırıyoruz. İkinci önemli kısım da burası. Observe ile üretilmiş bir nesnenin herhangi bir özelliğini okurken, yine "attr" fonksiyonunu kullanmak gerekiyor ancak bu sefer parametre olarak sadece özellik adını geçiyoruz.

    obj.attr({
        deger1: 20,
        deger2: "Veli"
    });

Burada, aynı anda birden fazla özelliğin değerinin nasıl değiştirildiğini görüyoruz. Sonrasında da iki özelliğin de değerini ekrana yazdırıyoruz.

Biliyorum, buraya kadar Observe sınıfının bir hayrını görmedik. Hatta "new Object()" ile nesne tanımlaması yapsaydık, özelliklere direk değer atar ve okurduk. Şimdi bir de başımıza "attr" fonksiyonu çıktı. Ama var bir bildiğim, biraz sabret.

Hemen ara vermeden ikinci örneğimize geçelim. "program.js" dosyamızın içeriğini aşağıdaki şekilde değiştirelim.

"use strict";

$(document).ready(function () {

    var obj = new can.Observe({
        deger1: 1,
        deger2: "Ali"
    });

    obj.bind("deger1", function (event, newVal, oldVal) {

        $("body").append("Eski : " + oldVal + ", Yeni : " + newVal + "<br>");

    });

    obj.bind("change", function (event, attr, how, newVal, oldVal) {

        $("body").append(attr + ", " + how + ", Eski : " + oldVal + ", Yeni : " + newVal + "<br>");

    });

    obj.attr("deger1", 10);

});

Bu örneğin hazır yazılmışını çalıştırmak için buraya tıklayabilirsin. Karşına aşağıdaki gibi bir sayfanın gelmesi gerekiyor.


Bu örneğimizde, Observe ile üretilmiş bir nesnenin değeri değiştiğinde, bize haber veren olayları yakalamayı görüyoruz. Normalde ileride anlatacağım EJS ile kullanırken böyle şeyler yapmamıza gerek kalmıyor, her şey otomatik oluyor ancak hem arka tarafta nasıl çalıştığını bilmek hem de gerektiğinde kendimize özel yapılar hazırlamak için Observe olaylarını anlamak önemli.

Örneğimizde tanımladığımız nesnemiz, bir önceki örnekte tanımladığımız ile aynı. Ardından nesneye iki adet Event Handler yazıyoruz ki, aslında ikisi de aynı işi yapıyor. Her iki kullanım şeklini de anlatmak için örneğe kattım. Şimdi sırasıyla bunları görelim.

    obj.bind("deger1"function (event, newVal, oldVal) {

        $("body").append("Eski : " + oldVal + ", Yeni : " + newVal +"<br>");

    });

Bu şekilde bir Event Handler yazdığımız zaman sadece "deger1" isimli özelliğin değeri değiştiği zaman fonksiyonumuz tetiklenir ve parametre olarak, özelliğin eski ve yeni değerleri gelir. Biz de bu değerleri ekrana yazdırdık.

    obj.bind("change"function (event, attr, how, newVal, oldVal) {

        $("body").append(attr + ", " + how + ", Eski : " + oldVal +", Yeni : " + newVal + "<br>");

    });

Bu şekilde bir Event Handler yazdığımız zaman ise, nesnemizin içerisindeki hangi özellik değişirse değişsin fonksiyonumuz tetiklenir. Fonksiyona "attr" ismi ile geçilen parametre, değişen özelliğin ismidir. "how" parametresi ise yapılan işlemi gösterir (Burada "set" işlemi). Diğer iki parametreyi zaten biliyorsun.

Örneğimizde bu Event Handler'ları yazdıktan sonra yaptığımız tek şey, "attr" fonksiyonu ile nesnemizi değiştirmek oldu. Böylece fonksiyonlarımız tetiklendi ve ekrana gerekli bilgiler yazıldı.

Biliyorum, git gide zorlaşıyor. Ama şimdi toparlayacağım inşallah. Son örneğimizi, EJS ve View ile birlikte gerçek bir kullanım örneği olarak veriyorum. "program.js" dosyamızın içeriğini aşağıdaki şekilde değiştirelim.

"use strict";

var obj;

$(document).ready(function () {

    obj = new can.Observe({
        deger1: 1,
        deger2: "Ali"
    });

    buildPage();
});

function buildPage() {

    $("body").append("");

    $("#testButton").click(testButtonClick);

    $("body").append("<br>");

    $("body").append(can.view("test.ejs", obj));

}

function testButtonClick() {

    obj.attr("deger2", "Veli");

};
Son bir şey daha; Aşağıdaki tek satırlık kodu, "program.js" dosyasının hemen yanına, "test.ejs" ismi ile kaydedelim.

<%= this.attr("deger2") %>

Bu örneğin hazır yazılmışını çalıştırmak için buraya tıklayabilirsin. Karşına aşağıdaki gibi bir sayfanın (soldaki) gelmesi gerekiyor. Butona tıklayınca da görüntü sağdaki gibi değişmesi gerekiyor

     

Öncelikle "test.ejs" dosyasının içeriği ve "program.js" dosyasındaki 23. satır ile ilgilenme. Bunları ayrı bir makalede geniş bir şekilde konuşacağız inşallah. Şimdilik bunlar hakkında tek bilmen gereken, Observe ile türettiğimiz nesnemizdeki "deger2" özelliğinin değerini ekrana yazıyor olduğu.

Programın başında, diğer örneklerimizde yaptığımız gibi nesnemizi aynı şekilde tanımlıyoruz. Ardından "buildPage" fonksiyonu içerisinde ekrana bir buton ekliyoruz. Butona basıldığı takdirde de, "testButtonClick" fonksiyonunun çalışmasını sağlıyoruz.

Son olarak fonksiyon içerisinde de, "degisken2" özelliğinin değerini "attr" fonksiyonu ile değiştiriyoruz. Özelliğin değeri değiştiği anda, ekrandaki yazının da değiştiğini fark edeceksin. Üstelik bunun için Observe sınıfına herhangi bir Event Hander yazmamıza da gerek kalmadı.

Hadi artık, toparlayalım. Bu çok basit bir örnek ama Observe sınıfını kullanma amacını anlamamıza yetiyor olması lazım. Sonuçta verinin kaynağı değiştiği anda, ekranda veriye bağlanmış göstericimiz de herhangi bir müdahaleye gerek kalmadan kendisini güncelledi.

Yeterli gelmedi mi? 

Peki, şöyle bir hayal kuralım. Çok kullanıcılı bir muhasebe programının cari hesaplar modülünü yazıyoruz. Ekranda cari hesap bilgileri veya herhangi bir cari hesabın detay bilgileri gözüküyor. Sunucu tarafı ile WebSocket üzerinden konuşuyoruz. Dolayısıyla, biz sunucuya istekte bulunmadan da, sunucu bize mesaj gönderebiliyor. Başka bir kullanıcı yeni bir cari hesap ekliyor/güncelliyor/siliyor veya o anda ekranda gözüken cari hesap bilgilerini güncelliyor. Sunucu, bağlı tüm istemcilere güncelleme mesajını gönderiyor ve istemcilerdeki veriler güncelleniyor. Bu veriler Observe sınıfından türediği ve ekrandaki kontrolleri de yukarıdaki örnekte gördüğümüz gibi bu nesnelere bağladığımız için, ekrandaki görüntü de anında güncelleniyor. Bunun için ekstra tek satır kod yazmamıza da gerek kalmıyor.

Makalemizi tamamlarken öğrendiklerimizi özetleyelim.
  • Nesneleri "new Object()" yerine Observe sınıfından türetirsek, nesnelerimiz güncellendiği zaman çeşitli aksiyonların alınmasını sağlayabiliriz.
  • Observe sınıfı ile üretilmiş nesnelerin değerlerini değiştirmek ve okumak için "attr" fonksiyonunu kullanmamız gerekir.
  • Observe sınıfının olayları ile güncelleme sırasında isteğimize özel aksiyonlar aldırabiliriz.
  • Can.JS içerisindeki EJS ve View ile birlikte kullanıldığında, herhangi bir Event Handler yazmaya gerek kalmaksızın tüm güncellemeler otomatik olarak gerçekleşir.


Yorum Gönder

 
Top