在網站中,經常會有某個欄目的資料在多個頁面同時使用到。比如新聞網站或電子商務網站的欄目列表,幾乎在很多頁面都會顯示欄目導航。對於這種多個頁面同時使用到的“資料區”在ASP.NET Web Form開發中,經常會將這些“資料區”獨立封裝為一個個Web控制項。那在VTemplate模板引擎裡又要如何做呢?在VTemplate模板引擎裡,提供了一種“模板塊解析器”介面。當VTemplate模板引擎解析並呈現VT模板資料時,如果發現某個<vt:template>標籤已定義“模板塊解析器”,則會構建此“模板塊解析器”執行個體並將解析權交給“模板塊解析器”,等其處理完後再繼續解析呈現標籤資料。其流程圖如下:
在<vt:template>標籤使用“模板塊解析器”,是利用其已定義的兩個特殊屬性:
| 名稱 |
說明 |
| render |
定義用於處理此模組資料的執行個體,格式:"類執行個體,程式集"。如果已定義此屬性但未定義rendermethod屬性,則類執行個體必須已實現ITemplateRender介面。(可不定義) |
| rendermethod |
定義用於處理此模組資料的類執行個體的方法,此方法必須已標記TemplateRenderMethodAttribute特性。(可不定義) |
如果是使用ITemplateRender介面來實現“模板塊解析器”,則只需要定義render屬性;如果用TemplateRenderMethodAttribute特性來實現“模板塊解析器”,則必須要定義render和rendermethod方法!
注意:TemplateRenderMethodAttribute特性的優先權最高,即如果同時定義了這兩個屬性,則不管render定義的類是否已實現ITemplateRender介面都會被忽略不用,而直接使用rendermethod定義的特性方法!
1、ITemplateRender介面。
|
/// <summary>
/// 模板塊資料的解析處理介面
/// </summary>
public interface ITemplateRender
{
/// <summary>
/// 預先處理解析模板資料
/// </summary>
/// <param name="template"></param>
void PreRender(Template template);
} |
從上可知,ITemplateRender介面只有一個聲明方法PreRender,用於接收處理VTemplate模板引擎轉交過來要進行解析的模板塊。
我們將《VTemplate模板引擎的使用--進階篇》的最後一個例子改一下,用ITemplateRender介面來處理那些新聞列表資料。
我們先構建一個已實現ITemplateRender介面的類,代碼如下:
namespace VTemplate.WebTester.Core { /// <summary> /// 模板塊解析器 /// </summary> public class CnblogsNewsRender : ITemplateRender { #region ITemplateRender 成員 /// <summary> /// 解析某個模板塊的資料 /// </summary> /// <param name="template"></param> public void PreRender(Template template) { //根據模板塊裡定義的type屬性條件取得新聞資料 List<News> newsData = NewsDbProvider.GetNewsData(template.Attributes.GetValue("type")); //設定變數newsdata的值 template.Variables.SetValue("newsdata", newsData); //取得模板塊下Id為newslist的標籤(也即是在cnblogs_newsdata.html檔案中定義的foreach標籤) Tag tag = template.GetChildTagById("newslist"); if (tag is ForEachTag) { //如果標籤為foreach標籤則設定其BeforeRender事件用於設定Variant 運算式{$:#.news.url}的值 tag.BeforeRender += (sender, e) => { ForEachTag t = (ForEachTag)sender; //取得當前項的值(因為foreach標籤的資料來源是List<News>集合,所以當前項的實值型別為News實體) News news = (News)t.Item.Value; //設定當前項的Variant 運算式的值.也即是"{$:#.news.url}"Variant 運算式 t.Item.SetExpValue("url", NewsDbProvider.GetNewsUrl(news)); //當新聞不可見時.你可以取消本次輸出 if (!news.Visible) e.Cancel = true; }; } } #endregion } } |
這樣我們就構造了一個“模板塊解析器”,在VT模板裡就可以直接使用了,如下:
<div class="side_block">
<h3 class="title_blue">相關新聞</h3>
<vt:template name="topnews" type="relating" file="cnblogs_newsdata.html" render="VTemplate.WebTester.Core.CnblogsNewsRender,VTemplate.WebTester" />
</div>
<div class="side_block">
<h3 class="title_yellow">熱點新聞</h3>
<vt:template name="topnews" type="hoting" file="cnblogs_newsdata.html" render="VTemplate.WebTester.Core.CnblogsNewsRender,VTemplate.WebTester" />
</div> |
具體的範例程式碼,請參考:http://net-vtemplate.googlecode.com/svn/src/VTemplate.WebTester/templaterender_test.ashx.cs
2、TemplateRenderMethodAttribute特性方法
TemplateRenderMethodAttribute特性方法的原形和ITemplateRender介面的PreRender差不多,即只能有一個參數,用於接收VTemplate模板引擎轉交過來要進行解析的模板塊對象。如下面例子代碼:
/// <summary> /// 解析某個模板塊的資料 /// </summary> /// <param name="template"></param> [TemplateRenderMethod(Description="解析新聞列表資料")] public void RenderNews(Template template) {
} |
而VT模板代碼就需要定義<vt:template>的rendermethod屬性,並且定義的值必須和類代碼中的方法名一致,如下面例子代碼:
<div class="side_block">
<h3 class="title_blue">相關新聞</h3>
<vt:template name="topnews" type="relating" file="cnblogs_newsdata.html" render="VTemplate.WebTester.Core.CnblogsNewsRenderMethod,VTemplate.WebTester" rendermethod="RenderNews" />
</div>
<div class="side_block">
<h3 class="title_yellow">熱點新聞</h3>
<vt:template name="topnews" type="hoting" file="cnblogs_newsdata.html" render="VTemplate.WebTester.Core.CnblogsNewsRenderMethod,VTemplate.WebTester" rendermethod="RenderNews" />
</div> |
具體的範例程式碼,請參考:http://net-vtemplate.googlecode.com/svn/src/VTemplate.WebTester/templaterendermethod_test.ashx.cs
TemplateRenderMethodAttribute特性方法與ITemplateRender介面比較,它的好處就是可在一個類執行個體中定義多個方法用於處理不同的模板塊,也即是說可在一個類執行個體裡定義多個“模板塊解析器”。
VTemplate項目託管在Google code上。
URL: http://net-vtemplate.googlecode.com/
SVN: http://net-vtemplate.googlecode.com/svn/src/VTemplate.Engine/
更多例子請參考VTemplate.WebTester項目:
http://net-vtemplate.googlecode.com/svn/src/VTemplate.WebTester/
或觀看線上示範例子:(感謝網友“DOLT”、“瘋子” 提供)
http://61.155.39.222:8888/index.ashx
註:已建立VTemplate模板引擎技術交流QQ群,歡迎各位加入參與項目開發或技術探討。QQ群:884468