原文地址:https://www.cnblogs.com/kingthy/archive/2011/08/31/2161039.html
現在讓我們瞭解一下VT裏最常用的function標籤。
Function標籤
其定義格式:
<vt:function var="變量" method="方法名" type="類型或實例變量" args="參數" output="true/false" />
它的作用即是在VT裏調用某個方法並將返回值賦給某個變量(定義了var的情況)。
假設我們現有這樣的一個類定義
namespace Test { public class Db { public DataTable GetData() { //這裏是詳細的代碼 } public DataTable GetDataByName(string name) { //這裏詳細的代碼 } public static DataTable GetDbData() { //這裏是詳細的代碼 } } }
現在我們要調用其定義的方法。
靜態方法的調用
在我們的程序代碼裏,如果要調用上面類的GetDbData靜態方法,我們一般這樣寫(完整寫法)
var data = Test.Db.GetDbData();
而將上面的語句轉成VT的模板標籤後,就需要寫成這樣的function標籤
<vt:function var="data" method="GetDbData" type="Test.Db" />
也就是function標籤裏的type屬性我們需要寫Db類的完整定義路徑。
實例方法的調用
在我們的程序代碼裏,如果要調用類實現的方法,我們一般這樣寫
var db = new Db(); var data = db.GetData();
而將上面代碼轉成VT的模板標籤後,我們的function標籤就是這樣寫
<vt:function var="data" method="GetData" type="$db" />
function標籤裏的type屬性我們寫爲“$db”,這就表示,我們調用的方法是“db”這個變量的實例方法。
但這個變量是從哪裏來呢?這個變量也是同程序代碼裏一樣,也是需要你在VT裏對其賦值,比如下面的示例代碼:
TemplateDocument document = TemplateDocument.FromFileCache(@"c:\template\test.html", Encoding.UTF8); document.SetValue("db", new Db());
上面代碼裏我們調用了SetValue方法,將“db”這個變量賦值到了VT模板裏,這樣模板裏就可以調用此變量的值或方法了。
帶參數的方法調用
如上面Db類裏的GetDataByName方法,在程序代碼裏我們一般這樣寫
var db = new Db(); var data = db.GetDataByName("car");
而對於帶參數的方法,在VT模板裏,我們就可以使用function標籤裏的args屬性,如下面
<vt:function var="data" method="GetDataByName" type="$db" args="car" />
而如果我們的參數不是一個常量值,而是一個變量值,我們也可以在args屬性裏調用,如下面
<vt:function var="data" method="GetDataByName" type="$db" args="$name" />
但name變量也是需要賦值纔可以使用(如通過SetValue方法),並且類型要一致,如果不一致,VT引擎將會嘗試轉換類型,如果類型轉換成功則執行方法,如果失敗將不會執行方法!!(參數類型不匹配時,因爲會嘗試轉換,所以這裏的效率會非常低,請儘量避免)
如果我們的方法裏有多個參數,我們可以通過定義多個args屬性,但要注意它們的定義順序是同方法的參數定義順序一樣的。如下面的示例
public DataTable GetDataBy(string name, int category) { //這裏詳細的代碼 }
VT裏的function標籤我們就可以寫成這樣
<vt:function var="data" method="GetDataBy" type="$db" args="car" args="1" />
參數的自定義
上面的例子裏,如果我們的方法參數非常多,用args定義是可以做到,但是卻非常的不直觀,並且如果參數定義的順序或類型一錯,將會導致我們的方法無法正確執行!如果能換一種方式,比如下面這樣的定義
<vt:function var="data" method="GetDataBy" type="$db" pName="car" pCategory="1" />
這樣我們的模板代碼看起來就非常的直觀明瞭。
VT模板裏允許在標籤裏添加自定義屬性,所以我們上面的標籤定義是符合格式的,但是我們爲了能使自定義屬性當作參數使用,我們就需要改寫GetDataBy方法,如下
public DataTable GetDataBy() { var document = TemplateDocument.CurrentRenderingDocument; var tag = document == null ? null : document.CurrentRenderingTag; if (tag == null) return null; var name = tag.Attributes.GetValue("pName"); var category = tag.Attributes.GetValue("pCategory").As<int>(0); //這裏是詳細的代碼 }
GetDataBy方法變成了無參數方法,並在方法裏我們調用了“TemplateDocument.CurrentRenderingDocument”獲取當前正在呈現解析數據的模板文檔對象,再通過“document.CurrentRenderingTag”獲取當前呈現解析數據的模板標籤對象。如果我們的GetDataBy方法是通過上面的function標籤調用執行的,則“document.CurrentRenderingTag”獲取到的標籤對象就是此function標籤,所以我們可以獲取此標籤裏的所有自定義屬性值,從而得到pName與pCategory裏定義的值。
注:各個模板標籤都有自己的關鍵屬性,這些是無法在自定義屬性裏獲取的,比如"id“、“name“這些是不能用做自定義屬性的。
用戶自定義方法
如果我們有些方法是私有的,比如
private DataTable GetUserData(object[] o) { }
或者匿名方法
UserDefinedFunction GetUserData = (o) =>
{
//這裏是詳細的處理代碼
};
對於這兩種情況,我們是無法直接通過function標籤調用的,因爲我們無法寫type屬性!因爲type屬性需要類名或者是類實例變量,並且是隻能調用公開方法
而對於這兩種情況,則我們需要先在模板裏註冊用戶自定義函數,才能通過function標籤調用。如下示例
TemplateDocument document = TemplateDocument.FromFileCache(@"c:\template\test.html", Encoding.UTF8); document.RegisterGlobalFunction("GetUserData", GetUserData);
註冊了自定義函數後,我們就可以寫無type屬性的function標籤,如下
<vt:function var="data" method="GetUserData" />
VT在處理這種沒有type屬性的方法時,將會在“自定義函數”列表裏查找同名的方法,如果找到則執行方法,否則不處理。
小提示
對於無參數的實例方法,可以直接在變量表達式裏執行,所以在任意標籤裏可直接使用,不一定需要通過function標籤執行,如下面示例
<vt:set var="data" value="$db.GetData()" />
<vt:foreach from="$db.GetData()" item="data">.......</vt:foreach>