Parser 是 Dojo 的解释器,专门用于解析 Dojo 的 widgets。其实平常我们基本不会涉及到使用 dojo/parser,但是,在某些特殊情况下,dojo/parser 可能会带给我们意想不到的便利。并且,它的一些配置参数也是非常值得我们注意的。
其实我们都知道,如何加载和运行 dojo/parser:
1 require(["dojo/parser"], function(parser){ 2 parser.parse(); 3 }); 4 5 require(["dojo/parser", "dojo/ready"], function(parser, ready){ 6 ready(function(){ 7 parser.parse(); 8 }); 9 }); 10 11 <script type="text/javascript" src="dojo/dojo.js" 12 data-dojo-config="parseOnLoad: true"></script>
上述示例中的三种方式都是可行的,可能最后一种方式是我们用的最多的。
如果单纯调用 parser.parse(),dojo/parser 会解析整个页面,其实我们也能给它限定范围:
1 require(["dojo/parser", "dojo/dom"], function(parser, dom){ 2 parser.parse(dom.byId("myDiv")); 3 }); 4 5 require(["dojo/parser", "dojo/dom"], function(parser, dom){ 6 parser.parse({ 7 rootNode: dom.byId("myDiv"); 8 }); 9 });
上述中的代码就将 dojo/parser 限定在了 ID 为“myDiv”的节点内部。dojo/parser 甚至都能改变解析的属性:
require(["dojo/parser", "dojo/dom"], function(parser, dom){ parser.parse({ scope: "myScope"}); }); <div data-myScope-type="dijit/form/Button" data-myScope-id="button1" data-myScope-params="onClick: myOnClick">Button 1</div>
很明显,当我们设定了“scope”为“myScope”之后,其解析的属性由“data-dojo-type”变为“data-myScope-type”。但是仅仅停留在这样对 dojo/parser 的简单的使用模式上,我们永远成不了高手,dojo/parser 还有更多的功能:
1 require(["dojo/parser", "dojo/_base/array"], function(parser, array){ 2 parser.parse().then(function(instances){ 3 array.forEach(instances, function(instance){ 4 // 处理扫描到的所有 widget 实例 5 }); 6 }); 7 });
可见,通过 dojo/parser,我们是可以基于它的返回值继续进行编程开发的,而不仅仅是利用它简单的解析 Dojo 的 widget。这里我们可以拿到所有解析出来的 widget 实例对象,并做出相应处理。
同样,我们还能直接调用“instantiate”方法实例化类:
1 <div id="myDiv" name="ABC" value="1"></div> 2 3 require(["dojo/parser", "dojo/dom"], function(parser, dom){ 4 parser.instantiate([dom.byId("myDiv")], { data-dojo-type: "my/custom/type"}); 5 });
这种做法和您在页面上写好 {data-dojo-type: "my/custom/type"},然后调用 parser.parse() 的效果是一样的。
既然说到了 dojo/parser,我们也要了解一些关于 dojo/parser 的默认解析行为,让我们看一个下面的例子:
1 //JavaScript 代码:定义类并解析 2 require(["dojo/_base/declare", "dojo/parser"], function(declare, parser){ 3 MyCustomType = declare(null, { 4 name: "default value", 5 value: 0, 6 when: new Date(), 7 objectVal: null, 8 anotherObject: null, 9 arrayVal: [], 10 typedArray: null, 11 _privateVal: 0 12 }); 13 14 parser.parse(); 15 }); 16 17 //HTML 代码:使用 MyCustomType 类 18 <div data-dojo-type="MyCustomType" name="nm" value="5" when="2008-1-1" 19 objectVal="{a: 1, b:'c'}" anotherObject="namedObj" arrayVal="a, b, c, 1, 2" 20 typedArray="['a', 'b', 'c', 1, 2]" _privateVal="5" anotherValue="more"></div>
这里我们先定义了一个 MyCustomType 类,并声明了它的属性,然后在后面的 HTML 代码中使用了该类。现在我们来看看 dojo/parser 对该类的变量的解析和实例化情况:
name: "nm", // 简单字符串
value: 5, // 转成整型
when: dojo.date.stamp.fromISOString("2008-1-1"); // 转成 date 类型
objectVal: {a: 1, b:'c'}, // 转成对象类型
anotherObject: dojo.getObject("namedObj"), // 根据字符串的特点转成对象类型
arrayVal: ["a", "b", "c", "1", "2"], // 转成数组类型
typedArray: ["a", "b", "c", 1, 2] // 转成数组类型
可见,成员变量的实例化和成员变量最初的初始化值有着密切联系,dojo/parser 会智能化的做出相应的处理,以达到您最想要的结果。注意,这里 _privateVal 的值没有传入到对象中,因为以“_”开头的变量会被 Dojo 理解成私有变量,所以其值不会被传入。另外,anotherValue 也不会实例化,因为该成员变量不存在。
当然,如果我们不喜欢 dojo/parser 的默认行为,我们可以在类里面实现“markupFactory”方法,这个方法专门用来实现自定义的实例化。
原文地址:http://www.ibm.com/developerworks/cn/web/1303_zhouxiang_dojocore/#major3