Düzey: Orta
Jack D Herrington
(jherr@pobox.com),
Kıdemli Yazılım Mühendisi, Leverage Software Inc.
20 Mart 2007
Bir şeylerin nasıl yanlış yapıldığını anlayarak, bunları doğru bir şekilde
yapmaya ilişkin birçok bilgi öğrenebilirsiniz. Kuşkusuz, Zamanuyumsuz
JavaScript + XML (Ajax) uygulamalarını yazmanın bir doğru, bir de yanlış yolu
vardır. Bu makalede, kaçınmak isteyeceğiniz bazı genel kodlama uygulamaları
anlatılmaktadır.
İnsanlar her şeyi ilk yaptıklarında doğru yapsalardı, dünya tamamıyla
farklı olurdu. Ajax için de bu kural geçerlidir. Bugüne kadar birçok kodlama yaptım,
kod yazdım, konuştum ve kendim de dahil Ajax geliştiricilerini destekledim. Bunlar
aracılığıyla, Ajax'ta nerelerde doğru ve yanlış yapıldığıyla ilgili çok şey
öğrendim. Son makalemde
(Beş yaygın
Ajax kalıbı: Kullanabileceğiniz yararlı Ajax tasarım kalıpları), Ajax
uygulamalarını doğru bir şekilde yazmaya ilişkin beş kalıp sundum. Bu makalede de
Ajax kodunda sık sık gördüğüm beş kötü kalıbı anlatacağım.
Kötü kalıp (anti-pattern) nedir diye sorabilirsiniz? Kötü
kalıp, herkesin kaçınması gereken bir sorun olarak yeterince sık görülen
bir uygulama tasarımı kusurudur. Burada genel olarak konuşuyorum. Sözdizimi hataları ve
bağlayıcı sorunları buna dahil edilmemelidir.
Çoğu geliştirici iyi bir kötü kalıp örneğini duymuştur: Web
sitelerinde SQL (Structured Query Language; Yapısal Sorgu Dili) güvenlik açığı
saldırılarına neden olan SQL kitaplıklarının yanlış kullanımı. Bu kötü kalıp,
şirketlerin gelirlerini kaybetmelerine, müşteri kayıtlarının açığa çıkmasına neden
olmuştur ve ne yazık ki, her programlama dilinde gerçekleştirilebilmektedir. Bu
nedenle, bunun nasıl ve neden olduğunu ve bundan nasıl kaçınılacağını anlamak
önemlidir.
Bu, kötü Ajax kalıpları için de geçerlidir. Bu kusurların şirketlerin
gelirlerinde milyarlarca dolarlık kayba neden olacağını söylemiyorum. Ancak, bunlar
sunucuların arızalanmasına neden olabilir ya da müşteri deneyimini
kötüleştirebilirler ve hem sinir bozucu, hem de pahalıya mal olabilirler.
Nelerin yanlış gidebileceğini anlarsanız, çok şey öğrenebilirsiniz.
Genellikle, Ajax'ın yalnızca bir sayfa yüklendikten sonra sunucudan XML
verilerini almak için kullanılan bir yöntem olduğu düşünülür. Bu çok sınırlı bir
görüştür ve yanlış uygulandığında, uygulamalarda performans sorunlarına neden
olabilir. Bu makalede, bunun neden yanlış olduğunu ve bunu nasıl düzeltebileceğinizi
göstereceğim.
İhtiyacınız
olmadığında bir zamanlayıcıyı yoklama
Gördüğüm Ajax sorunlarının birçoğu, JavaScript dilinde oluşturulan
zamanlayıcı işlevselliğinin yanlış kullanılmasından kaynaklanıyor. Anahtar yöntem,
window.setInterval() yöntemidir. Bu yöntemi ne zaman görürseniz görün,
aklınızda hemen bir soru işareti oluşmalıdır: Neden bu kişi bir zamanlayıcı
kullanıyor? Elbette, zamanlayıcıların kendi kullanım amaçları vardır --
canlandırmalar gibi.
window.setInterval() yöntemi, sayfanın belirli aralıklarla
-- örneğin, her saniye gibi -- belirli bir işlevi geri arayacağını belirtir. Konu bu
zamanlayıcılar olduğunda çoğu tarayıcı iyi olduğunu iddia eder, ancak temel olarak
JavaScript tek iş parçacıklı çalıştığından bunu nadiren başarırlar. Bir saniye
değerini ayarlarsanız, geri aramayı 1 saniye, 1.2 saniye ya da 9 saniye sonra
alabilirsiniz.
Zamanlayıcının kesinlikle gerekli olmadığı bir örnek, Ajax isteğinin
bitişini izlemektir. Liste 1'deki örneğe bakın.
Liste 1. Antipat1a_polling.html
<html><script>
var req = null;
function loadUrl( url ) {
if(window.XMLHttpRequest) {
try { req = new XMLHttpRequest();
} catch(e) { req = false; }
} else if(window.ActiveXObject) {
try { req = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try { req = new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) { req = false; }
} }
if(req) {
req.open('GET', url, true);
req.send('');
}
}
window.setInterval( function watchReq() {
if ( req != null && req.readyState == 4 && req.status == 200 ) {
var dobj = document.getElementById( 'htmlDiv' );
dobj.innerHTML = req.responseText;
req = null;
}
}, 1000 );
var url = window.location.toString();
url = url.replace( /antipat1a_polling.html/, 'antipat1_content.html' );
loadUrl( url );
</script><body>
Dynamic content is shown between here:<br/>
<div id="htmlDiv" style="border:1px solid black;padding:10px;">
</div>And here.</body></html>
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat1a_polling.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
setInterval çağrısını alıncaya kadar her şey yolundaymış
gibi görünür. Bu çağrı, isteğin durumunu izleyecek ve daha sonra, yüklenen
malzemeden sayfanın içeriğini belirleyecek bir zamanlayıcı ayarlar.
Bir isteğin tamamlandığının kısa sürede nasıl anlaşılacağına ilişkin
soruna daha iyi bir çözüm göstereceğim. Bu arada, Liste 2'de sayfanın istekte
bulunduğu dosya gösterilmektedir.
Liste 2. Antipat1_content.html
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat1_content.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Şekil 1'de, sayfa, tarayıcımda görüntülendiği
şekilde gösterilmektedir.
Şekil 1. HTML belgesine yerleştirilen
içerik
Şimdi kendinize şunu sorabilirsiniz: "Peki, bu çalışıyor, değil mi?
Bozuk değilse neden düzeltiyoruz?" Aslında bozuk, çünkü çok yavaş çalışıyor.
Zamanlayıcı bir saniyelik aralığa ayarlandığında, zamanlayıcı kapanana kadar istek
çoktan tamamlanır. Bu nedenle, sayfa önce boş bir kutuyla görüntülenir, daha
sonra bir saniye beklersiniz ve sonra içerik görüntülenir. Çok kötü!
Çözüm nedir? Ajax, doğası gereği zamanuyumsuzdur. Bir isteğin ne zaman
tamamlandığını görmek için bir yoklama döngüsüne ihtiyacınız yok mu?
Görünüşe göre, pek de değil. Liste 3'te
gösterdiğim gibi, XMLHTTPRequest nesnesinin tamamı,
onreadystatechange adı verilen bir geri arama düzeneği sağlar. (Ne
güzel bir ad, VAX PDP/11s'yi hatırlatıyor).
Liste 3. Antipat1a_fixed.html
<html><script>
var req = null;
function processReqChange() {
if (req.readyState == 4 && req.status == 200 ) {
var dobj = document.getElementById( 'htmlDiv' );
dobj.innerHTML = req.responseText;
}
}
function loadUrl( url ) {
...
if(req) {
req.onreadystatechange = processReqChange;
req.open('GET', url, true);
req.send('');
}
}
var url = window.location.toString();
url = url.replace( /antipat1a_fixed.html/, 'antipat1_content.html' );
loadUrl( url );
</script>
...
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat1a_fixed.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Bu yeni kod, yalnızca istek nesnesinin, bu
onreadystatechange geri aramasına yanıt olarak değişip değişmediğine
bakar. Daha sonra, tamamlandığında sayfayı günceller.
Sonuç, yıldırım hızıyla yüklenen bir sayfadır. Sayfa görüntülenir ve
neredeyse yüklenir yüklenmez yeni içerik kutuya yerleştirilir. Neden? Çünkü, istek
tamamlanır tamamlanmaz, kod çağrılır ve sayfa doldurulur. Anlamsız zamanlayıcılarla
ortalığı karıştırmaya gerek yoktur.
Başka bir yoklama kötü kalıp değişkeninde, bir sayfa bir isteği
sunucuya, istek değişmemiş olsa bile üst üste yeniden sunar. Liste
4'te gösterilen arama sayfasını ele alalım.
Liste 4. Antipat1b_polling.html
<html><script>
var req = null;
function processReqChange() {
if (req.readyState == 4 && req.status == 200 ) {
var dobj = document.getElementById( 'htmlDiv' );
dobj.innerHTML = req.responseText;
}
}
function loadUrl( url ) {
...
}
window.setInterval( function watchSearch() {
var url = window.location.toString();
var searchUrl = 'antipat1_content.html?s='+searchText.value;
url = url.replace( /antipat1b_polling.html/, searchUrl );
loadUrl( url );
}, 1000 );
</script><body><form>
Search <input id="searchText" type="text">:<br/>
<div id="htmlDiv" style="border:1px solid black;padding:10px;">
</div></form></body></html>
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat1b_polling.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Sayfayı Şekil 2'de tarayıcımda çalıştığı şekliyle
görebilirsiniz.
Şekil 2. Dinamik yanıt alanlı arama
alanı
Çok hoş. Görünüşünden, bu sayfa birçok şeyi anlatmaktadır. Arama
metnini değiştirdiğimde, sonuç alanı yeni ölçüte dayalı olarak değişiyor (aslında
değişmiyor, ancak isteğin arkasında gerçek bir arama motoru olsa, değişirdi.)
Buradaki sorun, JavaScript kodunun, arama alanındaki içerik değişmese
bile isteği tekrarlamak için window.setInterval öğesini kullanmasıdır.
Bu, ağ bant genişliğinin ve sunucu süresinin harcanmasına neden olur. Sık
kullanılan sitelerde bu ikisi korkunç bir birleşim olabilir.
Çözüm, Liste 5'te gösterilen şekilde arama
kutusunda olay geri aramalarını kullanmaktır.
Liste 5. Antipat1b_fixed.html
<html><script>
var req = null;
function processReqChange() { ... }
function loadUrl( url ) { ... }
var seachTimer = null;
function runSearch()
{
if ( seachTimer != null )
window.clearTimeout( seachTimer );
seachTimer = window.setTimeout( function watchSearch() {
var url = window.location.toString();
var searchUrl = 'antipat1_content.html?s='+searchText.value;
url = url.replace( /antipat1b_fixed.html/, searchUrl );
loadUrl( url );
seachTimer = null;
}, 1000 );
}
</script><body><form>
Search <input id="searchText" type="text" onkeyup="runSearch()">:<br/>
<div id="htmlDiv" style="border:1px solid black;padding:10px;">
</div></form></body></html>
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat1b_fixed.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Burada, runSearch() işlevini, arama kutusunun
onkeyup() yöntemine bağladım. Bu şekilde, kullanıcı arama kutusuna bir
şey yazdığında geri aranmamı sağladım.
runSearch() işlevinin yaptığı oldukça güzeldir. Sunucuya
çağrıda bulunacak ve aramayı çalıştıracak ikinci bir yöntem için tek bir zamanaşımı
değeri ayarlar. Ayrıca, ayarlamadan önce geçmişse bu zamanaşımı değerini
temizler. Neden? Çünkü bu, kullanıcının çok miktarda metin yazmasına olanak tanır;
daha sonra, kullanıcı son tuşa bastıktan bir saniye sonra arama çalıştırılır. Bu
şekilde, kullanıcı sürekli olarak titreyen görüntüyle rahatsız olmaz.
Geri aramada dönüş
sonuçlarının incelenmemesi
Birçok kötü Ajax kalıbı, XMLHTTPRequest nesnesinin
mekanizması yanlış anlaşıldığı için ortaya çıkar. Sık karşılaştıklarımdan biri,
kullanıcıların geri aramadaki nesnenin readyState ya da
status alanlarını incelememelerinden kaynaklanır. Ne demek istediğimi
daha iyi anlamak için Liste 6'ya bakın.
Liste 6. Antipat2_nocheck.html
<html><script>
var req = null;
function processReqChange() {
var dobj = document.getElementById( 'htmlDiv' );
dobj.innerHTML = req.responseText;
}
...
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat2_nocheck.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Her şey düzgün görünüyor. Küçük isteklerde ve bazı tarayıcılarda,
düzgün çalışabilir. Ancak, birçok istek, tamamlanmadan önce
onreadystatechange işleyicisine birkaç çağrı gönderecek kadar
büyüktür. Bu nedenle, geri aramanız eksik verilerle çalışıyor olabilir.
Bunun doğru şekli Liste 7'de gösterilmiştir.
Liste 7. Antipat2_fixed.html
<html><script>
var req = null;
function processReqChange() {
if (req.readyState == 4 && req.status == 200 ) {
var dobj = document.getElementById( 'htmlDiv' );
dobj.innerHTML = req.responseText;
}
}
...
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat2_fixed.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Ek koda gerek yoktur ve her tarayıcıda çalışır.
Bu sorunun Windows® Internet Explorer® 7 programında, diğer
tarayıcılardan daha ciddi olduğunu fark ettim. Internet Explorer 7,
onreadystatechange nesnesini çok fazla geri arıyor -- küçük
isteklerde bile çok. Bu nedenle, en azından işleyicileriniz doğru yazılmış
olmalı.
HTML'in daha uygun
olacağı durumlarda karmaşık XML geçirilmesi
Birlikte çalıştığım bir şirkette, tüm konuşmalar "ağın ön saflarında
bilgi" olması üzerineydi. Aslında fikir basitti; işin tümünü sunucuda yapmak yerine
masaüstünde yapmak için tarayıcının akıllı özellikleri kullanmak.
Ancak, sayfalarınıza ne kadar çok bilgi koyarsanız orada o kadar çok
JavaScript kodu kullanmanız gerekir. Bunun büyük bir olumsuz tarafı vardır: Tarayıcı
uyumluluğu. Önemsiz olmayan her JavaScript kodu satırını gerçekten de tüm popüler
tarayıcılarda -- ya da en azından, genellikle müşterilerinizin kullandıklarında --
sınamanız gerekir. Ve bu, iş anlamına gelir. Örneğin, Liste
8'deki karmaşık Ajax koduna bakalım.
Liste 8. Antipat3_complex.html
<html><head><script>
var req = null;
function processReqChange() {
if (req.readyState == 4 && req.status == 200 && req.responseXML ) {
var dtable = document.getElementById( 'dataBody' );
var nl = req.responseXML.getElementsByTagName( 'movie' );
for( var i = 0; i < nl.length; i++ ) {
var nli = nl.item( i );
var elYear = nli.getElementsByTagName( 'year' );
var year = elYear.item(0).firstChild.nodeValue;
var elTitle = nli.getElementsByTagName( 'title' );
var title = elTitle.item(0).firstChild.nodeValue;
var elTr = dtable.insertRow( -1 );
var elYearTd = elTr.insertCell( -1 );
elYearTd.innerHTML = year;
var elTitleTd = elTr.insertCell( -1 );
elTitleTd.innerHTML = title;
} } }
function loadXMLDoc( url ) {
if(window.XMLHttpRequest) {
try { req = new XMLHttpRequest();
} catch(e) { req = false; }
} else if(window.ActiveXObject) {
try { req = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try { req = new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) { req = false; }
} }
if(req) {
req.onreadystatechange = processReqChange;
req.open('GET', url, true);
req.send('');
}
}
var url = window.location.toString();
url = url.replace( /antipat3_complex.html/, 'antipat3_data.xml' );
loadXMLDoc( url );
</script></head><body>
<table cellspacing="0" cellpadding="3" width="100%"><tbody id="dataBody">
<tr>
<th width="20%">Year</th>
<th width="80%">Title</th>
</tr>
</tbody></table></body></html>
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat3_complex.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Bu kod, Liste 9'da gösterilen XML dosyasındaki
verileri okur ve bunları, bir tablo halinde düzenler.
Liste 9. Antipat3_data.xml
<movies>
<movie>
<year>1993</year>
<title>Jurassic Park</title>
</movie>
<movie>
<year>1997</year>
<title>The Lost World: Jurassic Park</title>
</movie>
<movie>
<year>2001</year>
<title>Jurassic Park III</title>
</movie>
</movies>
|
Sonucu Şekil 3 içinde görebilirsiniz.
Şekil 3. Karmaşık film listesi sayfası
Bu, kötü bir kod değildir. Aslında yalnızca nispeten basit bir görevi
gerçekleştirmek için çok fazla kod kullanılmıştır. Sonuçta görüntülenen sayfa o
kadar da karmaşık değildir. İstemci tarafında sıralama ya da arama yapılamaz.
Aslında, XML ile HTML arasındaki bu karmaşık dönüştürmeyi gerçekleştirmek için
neredeyse hiç neden yoktur.
Sunucunun, Liste 10'daki gibi XML yerine HTML
kullanması daha kolay olmaz mıydı?
Liste 10. Antipat3_fixed.html
<html><script>
var req = null;
function processReqChange() {
if (req.readyState == 4 && req.status == 200 ) {
var dobj = document.getElementById( 'tableDiv' );
dobj.innerHTML = req.responseText;
}
}
function loadUrl( url ) { ... }
var url = window.location.toString();
url = url.replace( /antipat3_fixed.html/, 'antipat3_content.html' );
loadUrl( url );
</script><body><div id="tableDiv"></div></body></html>
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat3_fixed.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Gerçekten de daha basit. Tüm karmaşık tablo satırı ve hücre
yaratma kodu, sayfadaki bir <div> biçim iminin tek bir
innerHTML takımıyla değiştirildi. İşte bu!
Sunucudan döndürülen HTML Liste 11'de
gösterilmiştir.
Liste 11. Antipat3_content.html
<table cellspacing="0" cellpadding="3" width="100%">
<tbody id="dataBody">
<tr>
<th width="20%">Year</th>
<th width="80%">Title</th>
</tr>
<tr>
<td>1993</td>
<td>Jurassic Park</td>
</tr>
<tr>
<td>1997</td>
<td>The Lost World: Jurassic Park</td>
</tr>
<tr>
<td>2001</td>
<td>Jurassic Park III</td>
</tr>
</tbody>
</table>
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat3_content.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Her şeyde olduğu gibi, işlemenin sunucu ya da istemci tarafında
gerçekleşmesi işin gereksinimlerine bağlıdır. Bu örnekte, iş nispeten basittir:
Bir film tablosu oluşturma. İş daha karmaşık olsaydı -- sıralama, arama, ekleme ya
da silme ya da bir film tıklatıldığında daha fazla bilginin gösterilmesi gibi
dinamik etkileşim -- istemci tarafında daha karmaşık kod görülebilirdi. Aslında, bu
makalenin sonunda, sunucuya çok fazla yük yerleştirmeye ilişkin karşı sav
hakkında bilgi verirken istemci tarafında sıralama yapmayı göstereceğim.
Tüm bunların belki de en mükemmel örneği Google Maps uygulamasıdır.
Google Maps, zengin istemci tarafı kodu ile sunucu tarafındaki akıllı harita
altyapısını karışık kullanarak mükemmel bir iş yapar. Bu hizmeti, nerede hangi
işlemenin gerçekleştirileceğinin nasıl belirleneceğine örnek olarak gösteriyorum.
JavaScript kodu
geçirilmesi gerekirken XML kodunun geçirilmesi
Web tarayıcılarının XML veri kaynaklarını okumasını sağlamak ve bunları
dinamik olarak dönüştürmekle ilgili yapılan tüm bu reklam karşısında,
kullanılabilecek tek yöntemin bu olduğunu düşünebilirsiniz. Ancak, yanılırsınız. Çok
zeki mühendisler, XML yerine JavaScript kodunu göndermek için Ajax aktarım
teknolojisini kullanmışlardır. Liste 12'deki film tablosu
örneğini ele alalım.
Liste 12. Antipat4_fixed.html
<html><head><script>
var req = null;
function processReqChange() {
if (req.readyState == 4 && req.status == 200 ) {
var dtable = document.getElementById( 'dataBody' );
var movies = eval( req.responseText );
for( var i = 0; i < movies.length; i++ ) {
var elTr = dtable.insertRow( -1 );
var elYearTd = elTr.insertCell( -1 );
elYearTd.innerHTML = movies[i].year;
var elTitleTd = elTr.insertCell( -1 );
elTitleTd.innerHTML = movies[i].name;
} } }
function loadXMLDoc( url ) { ... }
var url = window.location.toString();
url = url.replace( /antipat4_fixed.html/, 'antipat4_data.js' );
loadXMLDoc( url );
</script></head><body>
<table cellspacing="0" cellpadding="3" width="100%">
<tbody id="dataBody"><tr>
<th width="20%">Year</th>
<th width="80%">Title</th>
</tr></tbody></table></body></html>
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat4_fixed.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Bu, sunucudan XML okumak yerine JavaScript kodunu okur. Daha sonra, kod,
tabloyu hızlı bir şekilde oluşturmak için kullanabileceği verileri almak üzere
JavaScript kodundaki eval() işlevini kullanır.
JavaScript verileri Liste 13'te gösterilmiştir.
Liste 13. Antipat4_data.js
[ { year: 1993, name: 'Jurassic Park' },
{ year: 1997, name: 'The Lost World: Jurassic Park' },
{ year: 2001, name: 'Jurassic Park III' } ]
|
Bu işlevi kullanmak için sunucuyu JavaScript dilinde konuşturmanız
gerekir. Ancak, bu o kadar da zor bir şey değildir. Popüler Web dillerinin çoğu
zaten JavaScript Object Notation (JSON) çıktısını desteklemektedir.
Bunun yararları açıktır. Bu örnekte, JavaScript dili kullanılarak
istemciye yüklenen veri büyüklüğünde %52 tasarruf sağlanmıştır. Ayrıca,
performans artışı da gerçekleştirilmiştir. JavaScript sürümünün okunması %9 daha
hızlı olmuştur. %9 çok büyük bir değer gibi görünmeyebilir, ancak bunun çok basit
bir örnek olduğu unutulmamalıdır. Daha büyük veri blokları ya da daha karmaşık
yapılar, daha fazla XML ayrıştırma kodu gerektirirken, JavaScript kodu değişmeden
kalır.
Sunucu tarafında çok
fazla iş yapılması
Sunucu tarafında az iş yapılmasının karşı savı sunucuda çok iş
yapılmasıdır. Daha önce belirttiğim gibi bu dengeleyici bir işlemdir. Ancak,
sunucudaki iş yükünü azaltmaya bir örnek olarak, film tablosunun istemci tarafında
nasıl sıralanacağını göstermek istiyorum.
Liste 14'te sıralanabilir bir film tablosu
gösterilmiştir.
Liste 14. Antipat5_sort.html
<html><head><script>
var req = null;
var movies = null;
function processReqChange() {
if (req.readyState == 4 && req.status == 200 ) {
movies = eval( req.responseText );
runSort( 'year' );
} }
function runSort( key )
{
if ( key == 'name' )
movies.sort( function( a, b ) {
if ( a.name < b.name ) return -1;
if ( a.name > b.name ) return 1;
return 0;
} );
else
movies.sort( function( a, b ) {
if ( a.year < b.year ) return -1;
if ( a.year > b.year ) return 1;
return 0;
} );
var dtable = document.getElementById( 'dataBody' );
while( dtable.rows.length > 1 ) dtable.deleteRow( 1 );
for( var i = 0; i < movies.length; i++ ) {
var elTr = dtable.insertRow( -1 );
var elYearTd = elTr.insertCell( -1 );
elYearTd.innerHTML = movies[i].year;
var elTitleTd = elTr.insertCell( -1 );
elTitleTd.innerHTML = movies[i].name;
}
}
function loadXMLDoc( url ) { ... }
var url = window.location.toString();
url = url.replace( /antipat5_sort.html/, 'antipat4_data.js' );
loadXMLDoc( url );
</script></head><body>
<table cellspacing="0" cellpadding="3" width="100%">
<tbody id="dataBody"><tr>
<th width="20%"><a href="javascript: void runSort('year')">Year</a></th>
<th width="80%"><a href="javascript: void runSort('name')">Title</a></th>
</tr></tbody></table></body></html>
|
Canlı bir ortamda bunun nasıl görüneceğini görmek için
antipat5_sort.html
sayfasının çevrimiçi sürümünü görüntüleyin.
|
|
Bu, oldukça basit bir örnektir. Özellikle, birden çok sayfada
gösterilebilecek uzun film listelerinde işe yaramaz. Ancak, hızlı bir şekilde,
sayfayı yenilemeye gerek kalmadan sıralanan bir tablo ile, sunucuyu fazla zorlamayan,
sıradan bir sıralama işini kolay bir şekilde bir araya getirme konusunda iyi bir
örnektir.
Sonuç
Ajax konusunda birçok makale yazdım ve Ajax'la ilgili birçok çalışma
yaptım.
IBM
developerWorks üzerindeki Ajax forumu katılımcılarındanım. Dolayısıyla, Ajax ve
Ajax'ın nasıl doğru ve yanlış kullanıldığı konularında birkaç şey biliyorum. Sık
karşılaştığım durumlardan birisi, geliştiricilerin, Ajax'ın yalnızca bazı XML,
JavaScript ya da HTML kodlarını tarayıcıya gönderdiğini düşünerek Ajax'ın
karmaşıklığını hafife almasıdır. Ben, Ajax platformunu tam bir tarayıcı olarak
görüyorum -- aslında, popüler tarayıcılardan oluşan tam bir takım, çünkü tüm
tarayıcıların garipliklerini bilmeniz gerekir.
Sonuçta konu şuraya geliyor: Ajax'la ilgili öğrenilmesi gereken çok şey
ve yol boyunca yapılabilecek çok sayıda hata var. Umarım, bu makale bazı tuzaklardan
kaçınmanıza ya da içine düştüğünüzde kurtulmanıza yardımcı olur. Her iki durumda da,
başarılarınızdan çok şey öğrenebileceğiniz gibi genellikle hatalarınızdan daha çok
şey öğrenebilirsiniz.
Kaynaklar Bilgi Edinme
- developerWorks XML zone
sitesi : developerWorks XML zone sitesinden XML ile ilgili her şeyi
öğrenebilirsiniz.
- JSON ana sayfası: Sunucudan
istemciye JavaScript Object Notation verilerinin geçirilmesi için bir başvuru
noktası olan JSON sayfasını ziyaret edebilirsiniz.
-
ECMA
International sitesi: Burada, gerçekte ECMAScript olarak bilinen JavaScript
tanımlarını bulabilirsiniz.
- AjaxPatterns: Tamamen bu
konuya ayrılmış olan bu siteyi keşfedebilirsiniz.
-
Design
Patterns (Erich Gamma ve diğerleri, Addison-Wesley, 1995): Yazılım
mühendisliğinde kalıpların kullanılmasına ilişkin yeni ufuklar açan bu kitabı
okuyabilirsiniz.
-
Ajax
Design Patterns (Michael Mahemoff, OReilly, 2006): Özellikle Ajax ile
ilgili tasarım kalıplarını kapsayan yeni bir kaynak olan bu kitabı
okuyabilirsiniz.
- IBM XML
sertifikası : XML ve ilgili teknolojilerde nasıl bir IBM Sertifikalı Geliştirici
olabileceğinizi öğrenebilirsiniz.
-
XML teknik
kitaplığı: Çok çeşitli teknik makaleler ve ipuçları, senaryolar, standartlar ve
IBM Redbook yayınları için developerWorks XML Zone sitesine bakabilirsiniz.
-
developerWorks
teknik içerikli etkinlikler ve Web yayınları: Bu oturumlardaki teknolojiyi takip
edebilirsiniz.
- Ajaxian : Bu harika kaynakla, Ajax ve
bunu kullanan ön uç pencere bileşenlerle ilgili gelişmeleri izleyebilirsiniz.
Tartışma
Yazar
hakkında
|