[修練之路-JS]5. JS’s Observer pattern (using jQuery)

[修練之路-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()