ASP.Net AJax框架已經為我們提供了組件的設計模型
- Sys.Component:組件的基類,他實現了下面三個接口
- Sys.IDisposable:組件的銷毀接口
- Sys.INotifyDisposing:組件銷毀的通知接口
- Sys.INotifyPropertyChange:組件屬性改變的通知接口
下面是這些基類和接口的成員說明
Sys.Component get_events() 得到組件的事件列表 get_id()/set_id() 得到/設置組件的ID get_isInitialized() 得到組件是否已經初始化 initiialize() 組件的初始化方法 dispose() 組件的銷魂方法 raisePropertyChanged() 拋出組件屬性改變事件的方法
Sys.IDisposable dispose() 組件銷魂調用的方法
Sys.INotifyDisposing add_disposing 添加組件正在銷毀中的事件處理器 remove_disposing 移除組件正在銷魂中的事件處理器
Sys.INotifyPropertyChange add_propertyChanged() 添加組件屬性改變的事件處理器 remove_disposing 移除組件屬性改變的事件處理器
Sys.Component下有兩個派生類
- Sys.UI.Control:封裝DOM元素,概念上為一個(組合)控件
- Sys.UI.Behavior:擴展DOM元素,提供額外功能
直接繼承Component將不提供可視功能,繼承Control和Behavior可提供可視功能。因為Control和Behavior類封裝了DOM
全局容器:Sys._Application為一個全局容器類, 維護著全局的所有Component對象的生命周期。注意,所有的控件都必須在Load時才能使用Initialize和Dispose時不能時候。
下面有一個小例子,來示例如何簡單開發一個繼承於Component類的用戶組件
首先一個繼承與Component類的組件
// JScript 文件
Type.registerNamespace("Demo");
Demo.SimpleComponent = function()
...{
//調用基類的構造函數
Demo.SimpleComponent.initializeBase(this);
}
Demo.SimpleComponent.prototype =
...{
//重寫initialize方法
initialize : function()
...{
//調用基類的initialize方法,注意這段代碼放在我們代碼之前
Demo.SimpleComponent.callBaseMethod(this, "initialize");
alert("I have been initialized!");
},
//重寫dispose方法
dispose : function()
...{
alert("I have start dispose right now");
//調用基類的dispose方法,注意這段代碼放在我們的代碼之後
Demo.SimpleComponent.callBaseMethod(this, "dispose");
},
//組件的公開方法
sayHi : function()
...{
alert("Hello, I am the first Component");
}
}
//注冊類,基類為Sys.Component類
Demo.SimpleComponent.registerClass("Demo.SimpleComponent", Sys.Component);
首先我們需要通過ScriptManager引入組件類的JS文件
<ASP:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>...
<ASP:ScriptReference Path="~/SampleComponent.JS" />
</Scripts>
</ASP:ScriptManager>下面是如何使用組件的代
<script language="Javascript" type="text/Javascript">
function pageInit()
...{
alert("Page is initialized!");
//使用$create來創建一個組件,在pageInit方法中
//就算調用$create創建組件之後,仍然不能使用這個組件
$create(
Demo.SimpleComponent,
//使用JSon字符串的方式給組件的屬性賦值,
//這裡是給ID屬性賦值,還可以擴展
...{"id" : "simpleComponent"},
//使用JSon字符串的方式給組件的事件添加事件處理器。
...{"disposing": onDisposing}
);
}
//頁面默認的pageLoad事件處理器
function pageLoad()
...{
//通過ASP.Net AJax提供的$find方法找到組件
var simpleComponent = $find("simpleComponent");
simpleComponent.sayHi();
}
//組件的銷毀中事件處理器
function onDisposing()
...{
alert("Component is Disposing");
}
//給Application全局對象添加init事件的事件處理器
Sys.Application.add_init(pageInit);
</script>
這裡要注意一下,在組件內部重寫的dispose方法先被觸發,表示開始銷毀控件了,外部定義的onDisposing方法,表明控件已經正在銷魂中了。在dispose方法中還是可以操縱組件的內部成員的,比如說清空指令,避免內存洩漏,但是在onDisposing方法中是不能在操作組件的內部成員了的,因為已經開始銷毀組件了。
在這個例子中沒有掩飾raisePropertyChange的相關例子,在下面說明一下
- 在改變屬性時應該先判斷一下外部傳入的值是否和當前值不一樣,如果不一樣,在修改屬性值之後可以調用raisePropertyChange方法,參數為當前的屬性名,將PropertyChange事件拋出到頁面,讓頁面能獲取到哪個屬性被修改了。
- PropertyChange的方法簽名為sender和args,sender當然表明這個事件是哪個組件觸發的。args中可以通過ge_propertyName得到我們在組件中調用raisePropertyChange方法的參數。如果我們要得到sender(也就是組件)改變的屬性的改變後的值可以使用sender["get_" + propertyName].apply(sender)來得到。在這裡sender是作為一個字典來使用,並且通過apply方法將sender作為函數的this指針傳入到函數內部。