Asp.Net Ajax 學習筆記25 利用Microsoft AJAX Library開發客戶端組件(下)

這次課程的首先將$create方法的詳細簽名描述了一遍。

$create( type, properties, events,references, element);

那麼什麼時references呢?references是一個字典,保存了對象屬性與其它對象的關係,key是屬性名,value是其他對象id。保證在initialize方法被調用時屬性已經被設置爲所需對象,即使調用$create方法時其他對象還沒有創建。這個意思就是說,可以在create時,創建本組件的一個屬性,這個屬性保存的是其他對象的ID(可以說是引用)。在創建對象的properties和events時,可以使用json字符串的形式來描述。在下面的例子將會演示。

我們將演示一個複合控件, 複合控件主要會涉及到Control模型中的以下兩個方法:

  1.  raiseBubbleEvent(source, args):由子控件調用,將觸發的事件向父控件傳遞
  2. onBubbleEvent(source, args):父控件重寫該方法,用於接受子控件向上傳遞過來的事件

這兩個方法的主要作用是降低父控件和子控件之間的耦合關係,例如子控件不需要知道它的父控件是誰。

// JScript 文件
Type.registerNamespace("Demo");

//這是一個Button類,他代表一個子元素
Demo.Button = function(element)
{
    Demo.Button.initializeBase(
this, [element]);
    
    
this._context = null;
    
this._onClickHandler = null;
}


Demo.Button.prototype 
=
{
    initialize : 
function()
    
{
        Demo.Button.callBaseMethod(
this"initialize");
        
        
//創建一個onClickHandler的函數事件,將他根onClick函數綁定
        //在一起,那麼調用onClickHandler就是調用onClick函數
        this._onClickHandler = Function.createDelegate(this,
        
this._onClick);
        
        
//給Button組件裏的元素就是是DOM元素裏的button的click事件
        //綁定在一起,實際上就是綁定了OnClick函數.這裏爲什麼不直接
        //綁定OnClick函數,因爲我們需要通過createDelegate將當前this
        //作爲this上下文傳遞到onClick函數,如果直接綁定,當前this上
        //下文就是DOM元素裏的button
        $addHandler(this.get_element(), "click"
        
this._onClickHandler);
    }
,
    
    dispose : 
function()
    
{
        
this._onClickHandler = null;
        $clearHandlers(
this.get_element());
        
        Demo.Button.callBaseMethod(
this"dispose");
    }
,
    
    _onClick : 
function(e)
    
{
        
//將context作爲args的參數,傳遞到外部。
        var eventArgs = new Demo.ButtonClickEventArgs(this._context);
        
        
//這裏可以不用這個函數,直接調用raiseBubbleEvent
        this.raiseClick(eventArgs);
    }
,
    
    raiseClick : 
function(args)
    
{
        
//向父控件傳遞事件
        this.raiseBubbleEvent(this, args);
    }
,
    
    get_context : 
function()
    
{
        
return this._context;
    }
,
    
    set_context : 
function(value)
    
{
        
this._context = value;
    }

}



Demo.Button.registerClass(
"Demo.Button", Sys.UI.Control);

Demo.ButtonClickEventArgs 
= function(context)
{
    Demo.ButtonClickEventArgs.initializeBase(
this);
    
    
this._context = context;
}


Demo.ButtonClickEventArgs.prototype 
=
{
    get_context : 
function()
    
{
        
return this._context;
    }

}


Demo.ButtonClickEventArgs.registerClass(
"Demo.ButtonClickEventArgs", Sys.EventArgs);

Demo.ButtonList 
= function(element)
{
    Demo.ButtonList.initializeBase(
this, [element]);
    
    
this._itemDataList = null;
}


Demo.ButtonList.prototype 
= 
{
    initialize : 
function()
    
{
        Demo.ButtonList.callBaseMethod(
this"initialize");
        
for(var i = 0; i < this._itemDataList.length; i++)
        
{
            
this._createNewButton(this._itemDataList[i]);
        }

    }
,
    
    _createNewButton : 
function(data)
    
{
        
//創建一個button的DOM元素
        var buttonElement = document.createElement("input");
        buttonElement.type 
= "button";
        buttonElement.value 
= data.text;
        
//當前容器將button放置在本容器中。
        this.get_element().appendChild(buttonElement);
        
        
//使用JSon字符串的形式來初始化Demo.Button組件的屬性,
        //注意,設置屬性沒有使用_context和set_context,直接使用的
        //context,這裏系統自動轉換
        $create(
            Demo.Button,
            
{
                
"context" : data.context,
                
"parent" : this
            }
,
            
null,
            
null,
            buttonElement
        );
    }
,
    
    get_itemDataList : 
function()
    
{
        
return this._itemDataList;
    }
,
    
    set_itemDataList : 
function(value)
    
{
        
this._itemDataList = value;
    }
,
    
    
//相當於派生類重寫onBubbleEvent函數,當容器裏的控件拋出
    //raiseBubbleEvent事件時,這個函數將自動調用
    onBubbleEvent : function(source, e)
    
{
        
//調用raiseItemClick函數
        this.raiseItemClick(e);
        
        
//返回true表示,事件不會再向上層的容器控件傳遞
        return true;
    }
,
    
    add_itemClick : 
function(handler)
    
{
        
this.get_events().addHandler("itemClick", handler);
    }
,
    
    remove_itemClick : 
function(handler)
    
{
        
this.get_events().removeHandler("itemClick", handler);
    }
,
    
    raiseItemClick : 
function(args)
    
{
        
//得到itemClick事件的事件處理器
        var handler = this.get_events().getHandler("itemClick");
        
        
if(handler)
        
{
            
//調用外部的定義的itemClick的事件處理器
            handler(this, args);
        }

    }

}


Demo.ButtonList.registerClass(
"Demo.ButtonList", Sys.UI.Control);

這是容器類和子類的定義。

<div id="buttonList">
            
 
</div>

這是容器element的定義

<script language="javascript" type="text/javascript">
    
//利用Application初始化ButtonList控件
    Sys.Application.add_init(
        
function()
        
{
            
//定一個數組,作爲ButtonList的itemDataList屬性
            var dataList = 
            [
                
{
                    text : 
"Item1",
                    context : 
"Item1 has been clicked"
                }
,
                
{
                    text : 
"Item2",
                    context : 
"Item2 has been clicked"
                }
,
                
{
                    text : 
"Item3",
                    context : 
"Item3 has been clicked"
                }

            ];
            
            $create(
                    Demo.ButtonList,
                    
{
                        
"itemDataList" : dataList
                    }
,
                    
//定義itemClick事件的事件處理器
                    {
                        
"itemClick" : onItemClick
                    }
,
                    
null,
                   $get(
"buttonList")
                    
            );
        }

    );
    
    
function onItemClick(sender, args)
    
{
        alert(args.get_context());
    }

</script>

Behavior模型是 另一種可視化組件模型,繼承於Sys.UI.Behavior。 Control包裝DOM元素,Behavior爲DOM元
素提供功能(效果, etc)。 一個DOM元素只能由一個Control來包裝,但是可以由多個Behavior進行“裝飾”。

Behavior成員• 與Component組件相比唯一增加的屬性是name屬性。 由於一個DOM元素上可以添加多個Behavior,因此如果要通過元素獲得Behavior對象就要通過name屬性的值。 通過$get(“eleId”)["name_of_behavior"]來設置。Behavior模型沒有示例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章