[修練之路-JS]5. JS’s Observer pattern (using jQuery)
參考文件:
Essential JavaScript And jQuery Design Patterns – A Free New Book,
本篇為JavaScript Observer pattern 最終章, 由jQuery 來實作完整版
其中觀察者樣式實作是採用Ben Alman實作的 jquery.ba-tinypubsub https://gist.github.com/661855/c119783954e1b10551c4afef53b2c04fefcb7465
很快速精簡地做出jQuery plugin – codegenerate with observer pattern.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
(function($){
/*!
* jQuery Tiny Pub/Sub - v0.3 - 11/4/2010
* http://benalman.com/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
var generate = $({}); // 新增一個jQuery物件做為 Subject collection.
// 註冊觀察者
$.subscribe = function() {
generate.bind.apply( generate, arguments ); // arguments 為 (1)註冊名稱 (2)"觀察者"
};
// 取消觀察者
$.unsubscribe = function() {
generate.unbind.apply( generate, arguments ); // arguments 為 註冊名稱
};
// 發佈訊息
$.publish = function() {
generate.trigger.apply( generate, arguments ); // arguments 為 (1)註冊名稱 (2)"Subject" 的資料
};
// ---------------------------------------
// 實作及註冊觀察者 + jQuery extend function ,
// args 需定義 (1)取得z值方法 get_z() 及 (2)最大長度 maxlength
$.fn.codegenerate = function( args ){
var $this = $(this) ;
// 如果要取消註冊, 則同時將文字內容清為空白
if(args.unsubscribe){
$this.text("");
}else{
// 註冊觀察者
var text = "";
// 觀察者 參數generate:為透過jQuery建立的物件, 參數arguments:為Subject的資料(x,y)
var $func = function(generate, arguments){
if(text.length <= args.maxlength){ // 限於最大長度
var x = arguments.x;
var y = arguments.y;
var c = String.fromCharCode(65 + (x + y + args.get_z()) % 26); // 固定的演算法
text = text + c;
$this.text(text); // 運算結果
}
} ;
// 註冊觀察者
$.subscribe('codegenerate', $func);
}
}
})(jQuery);
$(function(){
// 實作TimeCodeGenerater
$('#time_gener').codegenerate(
{ get_z: function() { return new Date().getTime(); }, maxlength: 32 }
);
// 實作RandomCodeGenerater
$('#random_gener').codegenerate(
{ get_z: function() { return Math.random() * 100000 ; }, maxlength: 16 }
);
// 當滑鼠移動時, 發佈 x , y 值給觀察者
$('#holder').mousemove(function(e){
$.publish( "codegenerate", { x: e.offsetX, y: e.offsetY } ) ;
});
// 當按下[unsubscribe]時,移除註冊及值
$('#unsubscribe').click(function(){
$.unsubscribe('codegenerate');
$('#time_gener').codegenerate({unsubscribe:true});
$('#random_gener').codegenerate({unsubscribe:true});
});
});
</script>
</head>
<body>
<div>
請在空白處滑動你的mouse來產生代碼:
<div id="holder" style="height:300px; width:300px; border-width:1px; border-style:solid"></div>
<p>TimeCodeGenerator: <span id="time_gener" ></span> </p>
<p>RandomCodeGenerator: <span id="random_gener" ></span> </p>
</div>
<input type="button" id="unsubscribe" value="unsubscribe">
</body>
</html>
範例: http://jsfiddle.net/hectorlee369/hBetv/
ps. 之前的code實在"裏腳布", 在JS的世界裡, 跟之前學的OO程式語言相差甚遠, 動態的宣告方式, 可任意變化物件結構, 在在都讓人覺得驚奇.
剩下一個我覺得很難的題目:這是要怎麼開 spec 呀 !!!!
提供一個轉貼: Using jQuery .on() and .off() , jQuery 1.7 以後多了.on() 跟 .off()