原文位址:http://dotnetslackers.com/articles/atlas/xml_script_tutorial_part1.aspx
asp.net ajax xml-script教程(一)
原文釋出日期:2006.12.01
作者:Alessandro Gallo
翻譯:webabcd
概述
asp.net ajaxt提供了一種通過使用聲明程式模型來執行個體化用戶端類型的方法。下面的代碼給出了一個最簡單的例子,用來在頁面加載完畢後顯示一段資訊。
<%@ Page %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Hello XML-script</title>
</head>
<body>
<form id="form1"
runat="server">
<asp:ScriptManager ID="TheScriptManager" runat="server">
<Scripts>
<asp:ScriptReference
Assembly="Microsoft.Web.Preview"
Name="Microsoft.Web.Resources.ScriptLibrary.PreviewScript.js" />
</Scripts>
</asp:ScriptManager>
<script type="text/xml-script">
<page xmlns="http://schemas.microsoft.com/xml-script/2005">
<components>
<application load="page_load" />
</components>
</page>
</script>
<script type="text/javascript">
<!--
function page_load(sender, e)
{
alert("Hello World!");
}
//-->
</script>
</form>
</body>
</html>
注意,如果要使用xml-script特性的話,你需要在微軟的ajax站點下載下傳Futures CTP package,然後引用PreviewScript.js這個檔案,該檔案包含在Microsoft.Web.Preview程式集中。
聲明代碼總是要内嵌到一個腳本标記下,這個腳本标記的type屬性為text/xml-script。這段聲明代碼并不難了解。我們這裡有一個封裝了components元素的page根元素,它是一般xml-script的标準寫法。
在components元素下有一個application節點,設定其load屬性的值為一段javascript代碼的函數名稱。這個load屬性被解析成一個事件名稱,它的值指向一個用戶端函數,該用戶端函數将被增加到一個事件處理清單中。因為application元素被映射到了Sys.Application執行個體,是以當Sys.Application觸發了它的load事件的時候,page_load()将被調用。
這是如何實作的呢?聲明代碼是以xml元素和方法之間的映射為基礎的,屬性和事件是通過asp.net ajax類來被使用的。這種映射在每一個有類型描述符的類中都存在,而每一個有類型描述符的類都可以在聲明代碼中被使用。
類型描述符
類型描述符是一個對象,它用來描述類的屬性,方法和時間。每個想要提供類型描述符的類都必須實作ITypeDescriptorProvider接口,該接口定義了一個被稱做getDescriptor()的方法。這個方法必須傳回一個關聯到類的類型描述符。ITypeDescriptorProvider接口的原型如下:
Sys.Preview.ITypeDescriptorProvider.prototype = {
getDescriptor: Sys$Preview$ITypeDescriptorProvider$getDescriptor
}
另一個實作類型描述符的方法是給類增加描述符擴充。如果我們看一下PreviewScript.js檔案(在Sys.Preview命名空間下),會發現一些通過這個方法擴充出來的類型描述符。例如,接下來的代碼出示了Sys.Preview.Button類下的類型描述符。
Sys.Preview.UI.Button.descriptor = {
properties: [ { name: 'command', type: String },
{ name: 'argument', type: String } ],
events: [ { name: 'click' } ]
}
一個類型描述符就是一個對象(用“,”來分隔開每個“屬性-值”對比如{ name: "value" }就是一個“屬性-值”對),類型描述符的包含屬性如下:
·properties:一個屬性描述符的數組
·events:一個事件描述符的數組
·methods:一個方法描述符的數組
每一個數組都包含着一組描述符,此時這些描述符的作用是用來描述一個詳細的屬性、事件或方法的。例如,讓我們看一下事件數組中包含的描述符。
{ name : 'click' }
這個簡單的描述符告訴了我們,Button類有一個名稱為click的事件。屬性數組中包含兩個描述符。
{ name: 'command', type: String }
{ name: 'argument', type: String }
第一個描述符描述了一個被稱做command的屬性,類型是string型。第二個描述符告訴我們Button類有一個string類型的屬性,被稱做argument。
類型描述符能夠反映出用戶端類型,它從xml-script中被獨立出來。但是,xml-script解析器會在聲明代碼裡把屬性、方法和事件映射到xml元素中。
通過檢視這個類型描述符,我們即使不了解xml-script是如何工作的,也可以寫一段建立類型實體所需的聲明代碼。用Button類的類型描述符比較一下下面的這段xml
<button id="myButton" command="save" click="myButton_click" />
在上面這段xml裡,類的名字(Sys.Preview.UI.Button)被映射到了元素的名字(button),屬性都是一一對應的,而且事件也被映射成了屬性,這個事件屬性的值被設定成一個javascript函數名,由這個函數來負責處理click事件。
它的id屬性是從哪來的呢?Button類繼承自Sys.Component,它id屬性也是繼承自這個類。如果你在PreviewScript.js檔案中搜尋Sys.Component的類型描述符,你就會發現有一個id屬性的類型描述符。
Sys.Component.descriptor = {
properties: [ {name: 'dataContext', type: Object},
{name: 'id', type: String},
{name: 'isInitialized', type: Boolean, readOnly: true},
{name: 'isUpdating', type: Boolean, readOnly: true} ],
events: [ {name: 'propertyChanged'} ]
描述一個方法也需要提供方法參數的類型描述符。下面的代碼出示了從Sys.Preview.Net.ServiceMethodRequest類中提出來的方法屬性。
methods: [ {name: 'invoke', params: [ {name: 'userContext', type: Object} ] } ]
在這個例子中,這個類暴露了一個被稱做invoke的方法(通過方法描述符的name屬性得知)。這個方法接收一個被稱做userContext的參數,這個參數的類型是Object。參數在params屬性中被描述,每一個參數都有相關的參數描述符。
結論
在這篇教程裡,我們看到了在asp.net頁中包含聲明代碼的基礎示例。然後我們介紹了類型描述符,并且知道如何看懂它們。類型描述符為用戶端類型提供了了反射,它們在聲明程式模型中被使用,這種聲明程式模型允許使用xml文法來執行個體化用戶端類型。
在下一篇教程裡我們繼續學習類型描述符和xml元素之間的映射。