Board logo

标题: DojoX DTL 入门 -2 使用 DojoX DTL [打印本页]

作者: look_w    时间: 2018-8-23 20:40     标题: DojoX DTL 入门 -2 使用 DojoX DTL

使用 DojoX DTLDojoX DTL 包括文本和 HTML 两个实现,构造函数分别为 dojox.dtl.Template 和 dojox.dtl.HtmlTemplate。这两个构造函数都可以接受一个字符串或 URL 作为参数,HTMLTemplate 也可以传入一个 DOM 节点作为参数。
Template 只适用于文本,不能用它来操纵 DOM 节点。但是我们可以用它来产生文本,然后将生成的文本作为某个 DOM 节点的 innerHTML。
HTMLTemplate 是 Template 的扩展,这就是说 HTMLTemplate 不仅支持所有的 Template 操作,还支持直接对 DOM 节点的操作。例如一个节点位于 {% if %} 块标签中,如果 if 标签求值为真,那么这个节点会被添加到 DOM 中,如果 if 标签求值为假,则这个节点将会从 DOM 中移除。
Hello WordDojoX DTL 的使用与 Django Template Language 类似,首先创建一个 Template 对象,然后创建模板的上下文信息(context,可以理解为变量的集合),最后将 context 作为参数调用 Template 对象的 render 方法输出结果。
清单 2. Hello World
1
2
3
4
5
6
7
8
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");

var template = new dojox.dtl.Template("Hello {{ place }}!");
var context = new dojox.dtl.Context({
place: "World"
});
alert(template.render(context));




上面的例子首先调用 dojox.dtl.Template 构造函数创建了一个编译好的模板对象 template,该模板定义了对一个变量 place 的引用。这个模板对象可以在以后随时被调用,而不用每次都重新编译。然后调用 dojox.dtl.Context 创建了上下文对象 context,定义了 place 变量。这时调用 template.render(context) 会输出“Hello World”。
前面提到 Template 只适用于文本,但是产生的文本可以作为 DOM 节点的 innerHTML。为了方便这种类型的应用,Template 对象还有一个 update 方法,用来将模板输出的文本作为一个或多个节点的 innerHTML。update 方法有两个参数,第一个是要更新的节点引用、节点 ID 或是通过 dojo.query 返回的节点列表,第二个参数类型是对象或是 URL,作为模板的上下文信息。
在 dojo.query 中使用 DTL我们知道 dojo.query 返回一个 NodeList 对象,通过这个对象可以很方便地操作查询返回的结果集合。通过引入 dojox.dtl.ext-dojo.NodeList,我们可以将模板应用于 dojo.query 返回的结果集合。如下面的例子:
清单 3. dojo.query 中的模板使用
1
2
dojo.require("dojox.dtl.ext-dojo.NodeList");
dojo.query(".fruit").dtl("Fruit is: {{ fruit }}", { fruit: "apple" });




我们可以调用 NodeList 对象的 dtl 方法,将第一个参数作为模板,第二个参数作为上下文信息,然后把模板的输出结果作为 NodeList 中每个结果对象的 innerHTML。dtl 方法的参数同 Template 对象的 update 方法。
使用 DojoX DTL 创建 widget在创建自定义 widget 的时候,我们一般会将 dijit._Widget 和 dijit._Templated 作为父类。而通过 DojoX DTL 我们也能实现自定义 widget,如下面的例子:
清单 4. widget 示例
1
2
3
4
5
6
7
8
9
dojo.require("dojox.dtl._Templated");

dojo.declare("demo", [dojox.dtl._Widget, dojox.dtl._Templated] {
templateString: "<div>I like eating {{ fruit }}</div>",
postCreate: function(){
  this.fruit = "apple";
  this.render();
}
});




上面的例子使用了文本方式,当然我们也可以使用 HTMLTemplate,只要将 dojox.dtl._Templated 替换成 dojox.dtl._HtmlTemplated 即可。同 dijit widget 一样,我们也可以使用 templatePath,templateString 指定模板,使用 dojoAttachPoint 和 dojoAttachEvent 指定节点与 JavaScript 交互的属性。另外也可以为 render 方法指定 context,否则会将当前的 widget 对象作为 context。下面的例子说明了如何用 dojox.dtl._HtmlTemplated 来创建 widget。
清单 5. HTML 模板示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<html>
     <head>
     <title>dojo.DTL Demo</title>
    <script type="text/javascript" src="dojo/dojo.js" djConfig="parseOnLoad: true">
    </script>
    <script type="text/javascript">
        dojo.require("dijit.dijit");
        dojo.require("dojox.dtl._HtmlTemplated");
        dojo.require("dojo.parser");
        dojo.declare("Fruit", [dijit._Widget, dojox.dtl._HtmlTemplated], {
            oldRepl: "Fruit: ",
            items: ["apple", "banana", "orange"],
            keyUp: function(e){
            if(e.keyCode == dojo.keys.ENTER){
             var i = dojo.indexOf(this.items, e.target.value);
             if(i != -1){
                this.items.splice(i, 1);
             }else{
                this.items.push(e.target.value);
             }
             e.target.value = "";
             this.render();
             dojo.query("input", this.domNode).forEach("item.focus();");
                         }
                     },
templateString: '<div><input dojoAttachEvent="onkeyup: keyUp">
<ul>{% for item in items %}<li>{{oldRepl}} {{ item }}</li>{% endfor %}</ul>
</div>'
                 });
         </script>
     </head>
     <body>
         <div dojoType="Fruit"></div>
     </body>
</html>




首先创建了 widget 类 Fruit,定义了变量 oldRepl 和数据 items,以及 keyUp 函数,这个函数通过 dojoAttachEvent 与模板里的 input 元素的 onkeyup 事件绑定。在 templateString 里定义了一个输入框和一个列表,通过 for 标签输出水果列表。
在浏览器里打开该文件,显示效果如下:
图 1. HTML 模板示例效果图在输入框中输入水果名字,如果该水果名字在列表中已经存在,则从列表中删除该水果条目。如果列表中不存在该水果,则将该水果添加到列表中。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0