iT邦幫忙

9

jQuery method chain review

分享有關 jQuery method chain 相關的 api 與 method chain 的基本知識
所謂的 method chain ,主要是一種操作上 API 設計,是用來讓開發者開發程式時少打幾個字,
並且透過 method chain 更方便開發以及開發時能連貫自己思緒的一種表達式。

這種作法需要在設計上下功夫, jQuery 也為此著墨很多。

以 jQuery 為例,我們熟悉的 method 用法,如以下範例

$("div").filter(":first")
        .css("color","red")
        .css("background","white")
        .attr("name","hello");

如果換成非 chain ,想想看你需要寫多少程式碼。

var div = $("div"),
	tempdiv;
tempdiv = div.filter(":first");
tempdiv.css("color","red");
tempdiv.css("backround","white");

寫起來是不是很囉唆?


要討論 jQuery 的 method chain ,得先從 method chain 的原型來討論,

基本上 method chain 基本實作方式,
就是把本來 setter 或一般操作等原本無回傳值的函式,
改成回傳操作者自己。

For example

var Obj = {
	_valA:null,
	_valB:null,
	setA: function(val){
		this._valA = val;
		return this; //this is "Obj"
	},
	getA: function(){
		return this._valA;
	},
	setB: function(val){
		this._valB = val;
		return this; //this is "Obj"
	},
	getB: function(){
		return this._valB;
	},
	clearAll: function(){  //a general method
		this._valA = null;
		this._valB = null;
	}
};

在有這樣的程式碼的狀況下,你就可以呼叫這些 method ,
因為他們回傳的就是 Obj 本身(或者同型態的物件),
所以就可以達到反覆調用 Obj 的 method 的效果。

這裡是一個範例

Obj.setA("hi").setB("hi2").clearAll()
   .setA("A").setB("B");
alert(Obj.getA() +":"+ Obj.getB()); //will alert "A:B"

Runnable sample: http://jsfiddle.net/zCKRp/

單純就程式碼的實作你會發現「這裡沒有魔術」,
就只是單純的回傳值改變,從 undefined 變成調用者(caller) 本身。


通常也一定會有人會問,為什麼是 setter 而已,getter 呢?

像是 Obj.getB().getA() 這樣的寫法呢?

這樣當然不 work !

getB() 我們期待的是回傳「資料」,所以 getB() 已經要求要回傳數值,
當然就不能再用這資料做 method chain 。


那我們回頭過來說,jQuery 主要常用來作 method chain 用法的 api 有
find , filter, not , css setter , attr setter, data setter 等等等等。

所以我們又要回頭再看一次開頭提到的 jQuery 的範例:

$("div").filter(":first")
        .css("color","red")
        .css("background","white")
        .attr("name","hello");

結束了嗎?

還沒!

因為 jQuery 的人用的人多,所以--怪--特別需求也多,
jQuery 的 method chain 上還有一些特殊功能。

我們最後要介紹的兩個相關函式跟操作用法,並且介紹為什麼會有這麼--奇怪--特別需求。

在這裡我們先列出來:

andSelf()
http://api.jquery.com/andSelf/

end()
http://api.jquery.com/end/


@ andSelf()

用法是當我們作一些操作 query 出不同的 data set 時,
有時候我希望把之前的集合也拿回來一起操作,我就會需要這東西。

舉例,假設我想要拿到這一個跟下一個,有一個常見的 combo是

$(selector).next().andSelf()

<div id="parent">
   <div id="first">1</div>
   <div >2</div>
   <div >3</div>
   <div >4</div>
</div>

<script>
$("#first")		//此時為 [#first]
	.next() 	//此時為 [div]
	.andSelf()  // 此時為 [#first,div]  
	.append(":get you.");
</script>

Output

1:get you.
2:get you.
3
4

換成傳統寫法的話,大概就像是

<div id="parent">
   <div id="first">1</div>
   <div >2</div>
   <div >3</div>
   <div >4</div>
</div>

<script>
var item = $("#first"),		//此時為 [#first]
	newitem = item.next(); 	//此時為 [div]

newitem
	.add(item)  // 此時為 [#first,div]  
	.append(":get you.");
</script>

Output

1:get you.
2:get you.
3
4

它會幫你把呼叫 andSelf 之前的最後一個不同集合加回當前集合,變成新的集合。


@ end()

他的功用則是讓你找回上一層的集合

舉例

<div id="parent">
   <div id="first">1</div>
   <div >2</div>
   <div >3</div>
   <div >4</div>
</div>

<script>
$("#first")		//此時為 [#first]
	.next() 	//此時為 [div]
	.append(":get div")
	.end()  // 此時為 [#first]   (之前最後一個集合是 #first )
	.append(":get first.");
</script>

Output

1:get first.
2:get div
3
4

善用這些方法,基本上應該可以讓你寫程式寫得比較有趣一點,
method chain 雖然寫起來方便逗趣,但是可不要太依賴他喔!

確實的了解每個函式的回傳型態跟回傳值,
適當的組織程式碼跟排版,才是開發的不二法門。:)


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
wordsmith
iT邦高手 1 級 ‧ 2012-06-06 22:05:34

今天在找簡化程式碼的方法,突然想到jQuery的method chain 方法,就找到TonyQ大大這篇,馬上就拿來用了,讓程式碼看上去優雅不少。

謝謝

我要留言

立即登入留言