這次課程的首先將$create方法的詳細簽名描述了一遍。
$create( type, properties, events,references, element);
那麼什麼時references呢?references是一個字典,保存了對象屬性與其它對象的關係,key是屬性名,value是其他對象id。保證在initialize方法被調用時屬性已經被設置爲所需對象,即使調用$create方法時其他對象還沒有創建。這個意思就是說,可以在create時,創建本組件的一個屬性,這個屬性保存的是其他對象的ID(可以說是引用)。在創建對象的properties和events時,可以使用json字符串的形式來描述。在下面的例子將會演示。
我們將演示一個複合控件, 複合控件主要會涉及到Control模型中的以下兩個方法:
- raiseBubbleEvent(source, args):由子控件調用,將觸發的事件向父控件傳遞
- onBubbleEvent(source, args):父控件重寫該方法,用於接受子控件向上傳遞過來的事件
這兩個方法的主要作用是降低父控件和子控件之間的耦合關係,例如子控件不需要知道它的父控件是誰。
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>
這是容器element的定義
//利用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模型沒有示例。