[导入]Kingthy.Template模版引擎(讲四) -- 模版文档元素
模版文档元素是一个容器,用于装载其它模版元素.它可以是一段字符串也可以是一个文本文件.
一: 元素定义:
<template [属性="属性值" ...]>模版数据</template>
或者自闭合样式:
<template [属性="属性值" ...] />
已定义的属性:
属性名 |
属性功能 |
name |
设置某个模版文档的名称. 注: 此属性可以不设置(未设置时程序人员只能通过索引获取此模版文档)并且多个模版文档可以同名存在 例子: <template>这是未设置名称的情况</template> <template name="模版1">这是已设置的情况</template> |
file |
设置此模版文档的模版数据从此文件载入.此属性值可为绝对路径或相对路径.如果为相对路径则为相对其父级模版文档的路径地址. 例子: <template name="t1" file="C:\txt.txt" /> 则模版文档t1的模版数据为c:\txt.txt里的内容. 注:此属性不同于模版变量元素的file属性,在此属性设置的文件内容被载入时将会被模版引擎解析!! 如果存在此属性则忽略节点包含的模版数据.所以存在此属性时一般建议使用自闭合样式. 例子1: 如果c:\txt.txt文件的内容如下: 我的名字<$:name> 则上面的t1模版引文档里将包括一个模版文字元素对象"我的名字"和一个模版变量元素name 例子2: <template name="t1" file="c:\txt.txt">她的名字是<$:name></template> 因为模版文档t1已包含file属性,所以红色字的模版数据将会被模版引擎忽略也即不会解析到里面的模版变量元素name. |
charset |
设置载入file属性文件内容时使用的文件编码.此属性只有在设置file属性后有效. |
render |
设置模版文档的解析器实例. 格式:"解析器实例,解析器实例所在程序集" 例子: <template render="Kingthy.Web.TemplateWebApp.ClassTemplateRender,Kingthy.TemplateWebApp">.......</template> |
注:在模版文档里定义的属性可以被程序人员访问.
二, 模版文档的嵌套
模版文档嵌套即是在某个模版文档下还可以包含任意多个子模版文档元素,
例子: (带层次的下拉框):
<html> <head> <title> 模版文档的嵌套范例一 </title> </head> <body> <select name="ClassId"> <optgroup label="A栏目"> <option value="1">A--子栏目一</option> <option value="2">A--子栏目二</option> <option value="3">A--子栏目三</option> </optgroup> <optgroup label="B栏目"> <option value="4">B--子栏目一</option> <option value="5">B--子栏目二</option> <option value="6">B--子栏目三</option> </optgroup> <optgroup label="C栏目"> <option value="7">C--子栏目一</option> <option value="8">C--子栏目二</option> <option value="9">C--子栏目三</option> </optgroup> </select> </body> </html> |
改为页面模版(test1.html):
<html> <head> <title> 模版文档的嵌套范例一 </title> </head> <body> <select name="ClassId"> <template name="RootClass" remark="主模版文档"> <optgroup label="<$:RootClass.Title>"> <template name="ChildClass" remark="子模版文档"> <option value="<$:ChildClass.Id>"><$:ChildClass.Title></option> </template> </optgroup> </template> </select> </body> </html> |
程序代码处理(Test1.aspx):
//装载页面模版 TemplateDocumentParser docParser = new TemplateDocumentParser(this.GetAbsFilePath("skin/test1.html"), Encoding.Default); //获取RootClass TemplateDocument rootDoc = docParser.Document.Childs["RootClass"]; //获取ChildClass TemplateDocument childDoc = rootDoc.Childs["ChildClass"]; //获取所有绑定数据 DataTable table = GetClassDataTable(); //取得根级数据 DataRow[] rootRows = table.Select("RootId=0"); //绑定根级数据 //设置在绑定每行根级数据行时,处理对应的根级的子级列表数据 rootDoc.BindRowAfter += delegate(object s, TemplateBindRowAfterEventArgs ev) { //取得当前绑定行的数据 DataRow row = ev.RowData as DataRow; //获取对应根级栏目下的所有子栏目数据 DataRow[] childRows = table.Select(string.Format("RootId={0}", row["Id"])); //绑定当前行对应的数据列表 //绑定时设置模版变量名的前辍 childDoc.DataBind("ChildClass."); }; rootDoc.DataSource = rootRows; //绑定时设置模版变量名的前辍 rootDoc.DataBind("RootClass."); //输出数据 docParser.Document.Render(Response.Output); |
三, 模版文档解析器:
在某些场合下如果有多处地方(比如多个Web页面)都是引用同一种数据(比如新闻的排行与推荐新闻列表),那我们可以将这几处的共同处理方法都写在一个模版解析器里,这样就方便在页面模版中直接设置.这也就是render属性的作用.
*:ITemplateDocumentRender接口:
模版解析器必须实现ITemplateDocumentRender接口,此接口只有一个方法
ParseDocument(TempalteDocument document);
解析器由模版引擎负责调用,所以除必须实现ITemplateDocumentRender接口之外,还必须存在一个无参数的构造函数(因为模版引擎是通过反射构造此解析器实例).
*.模版文档解析器的使用:
当我们在解析输出(Document.Render)模版数据时,如果某个模版文档存在有render属性,则模版引擎将构建此模版文档的解析器实例并将此模版文档交由解析器处理.
我们将上面例子的页面模版改一下(test2.html):
<html> <head> <title> 模版文档的嵌套范例二</title> </head> <body> <select name="ClassId"> <template name="RootClass" remark="主模版文档" render="Kingthy.Web.TemplateWebApp.ClassTemplateRender,Kingthy.TemplateWebApp"> <optgroup label="<$:RootClass.Title>"> <template name="ChildClass" remark="子模版文档"> <option value="<$:ChildClass.Id>"><$:ChildClass.Title></option> </template> </optgroup> </template> </select> </body> </html> |
在这里我们已将RootClass这个模版文档交由Render去处理,所以我们的程序代码里就不需要再对它负责了.代码如下(Test2.aspx)
TemplateDocumentParser docParser = new TemplateDocumentParser(this.GetAbsFilePath("skin/test2.html"), Encoding.Default); docParser.Document.Render(Response.Output); |
在这个示例中.当我们的装载页面模版并解析输出(Render)模版数据时,模版引擎将会自动构建RootClass模版文档的解析器实例"Kingthy.Web.TemplateWebApp.ClassTemplateRender",并将RootClass模版文档做为方法参数调用ClassTemplateRender的ParseDocument方法.所以我们得到的最终结果和Test1.aspx的输出结果是一样的.
*.模版文档解析器的重复使用:
页面模版文档如下:(test3.html)
<html> <head> <title> 模版文档的嵌套范例三</title> </head> <body> <select name="ClassId"> <template name="RootClass" remark="主模版文档" render="Kingthy.Web.TemplateWebApp.ClassTemplateRender,Kingthy.TemplateWebApp"> <optgroup label="<$:RootClass.Title>"> <template name="ChildClass" remark="子模版文档"> <option value="<$:ChildClass.Id>"><$:ChildClass.Title></option> </template> </optgroup> </template> </select> <br /><br /> <table width="100%" border="1"> <template name="RootClass1" rootid="1" remark="限制只输出A栏目的数据" render="Kingthy.Web.TemplateWebApp.ClassTemplateRender,Kingthy.TemplateWebApp"> <tr> <td><$:RootClass.Title></td> <td> <table width="100%" border="1"> <template name="ChildClass" remark="子模版文档"> <tr> <td><$:ChildClass.Id>, <$:ChildClass.Title></td> </tr> </template> </table> </td> </tr> </template> </table> </body> </html> |
程序代码还是和上面一样(Test3.aspx)
TemplateDocumentParser docParser = new TemplateDocumentParser(this.GetAbsFilePath("skin/test3.html"), Encoding.Default); docParser.Document.Render(Response.Output); |
上面所有示例的源代码下载:
https://files.cnblogs.com/kingthy/TemplateWebApp.rar
文章来源:http://www.cnblogs.com/kingthy/archive/2008/03/21/1116688.html