dojo(六):声明式语法和dojo/parser


1、简介

使用Dojo有两种主要的方式,分别是编程式和声明式。编程式使用JavaScript实例化对象,并且所有的代码都编码在JavaScript中;声明式使用dojo/parser读取DOM,并解析出被特殊属性(后面我们会知道这个属性是data-dojo-type)装饰的节点和扩展控件行为的特定的<scrpt>标签。

这两种方式都有自己的优缺点,你可能同时使用这两种方式。本文主要讲解声明式语法,使用声明式语法,你需要考虑到下面几点:

 

  • 声明式语法非常简单,并且不需要更深的JavaScript只是。JavaScript可以实现的,声明式语法几乎都能实现,但是声明式语法有它的限制。
  • 由于声明式语法的本质(类似html标签),他的性能不如编程式好。因为需要使用dojo/parser解析DOM,并查找需要处理的节点。

2、实例化对象

声明式语法最常用的方式是实例化组件。实现方式是:添加特殊的属性(data-dojo-type)到html标签中,并使用dojo/parser读取文档和实例化组件。看个例子:

 

[html] view plain copy
  1. <button type="button" id="myButton" data-dojo-type="dijit/form/Button">  
  2.     <span>Click Me!</span>  
  3. </button>  

上面的例子中我们使用data-dojo-type指定了一个MID(模块ID,这里是Dojo Button),它会指示dojo/parser在该节点在DOM中的位置处实例化一个dijit/form/Button对象。

可以注意到我们添加了一个id属性,它在我们需要获取这个组件的引用时有用。Dijit的基本组件在实例化时,会查找存放他们的节点,如果有id属性,就会使用该id值在dijit/registry中注册,以便将来可以通过该id来引用组件。

我们上面只是放置了一个标签,接下来我们还需要激活dojo/parser。在引入AMD之前的版本,你可以使用Dojo配置data-dojo-config中的选项parseOnLoad:true来激活dojo/parser。这种使用方式在某些特殊情况下可能会导致非预想结果,因此建议在代码中显示的激活dojo/parser。

 

[html] view plain copy
  1. <script type="text/javascript" src="lib/dojo/dojo.js"  
  2.     data-dojo-config="async: true"></script>  
  3. <script type="text/javascript">  
  4.     require(["dojo/parser", "dojo/ready", "dijit/form/Button"],  
  5.     function(parser, ready){  
  6.         ready(function(){  
  7.             parser.parse();  
  8.         });  
  9.     });  
  10. </script>  

3、配置对象

使用dojo/parser实例化对象很强大,但是如果不能配置组件,就没有任何意义。因此需要一个机制能够在实例化时传入配置信息。

在Dojo的早期版本,我们使用往标签中添加属性的方式,即使属性不起作用。HTML5引进了一种该方式:允许自定义以data-开头的属性,并允许文档严格验证。因此我们使用专有的data-dojo-props属性来包含实例化时需要传送构造器的配置。 例如:

[html] view plain copy
  1. <button id="btn1" data-dojo-type="dijit/form/Button"  
  2.             data-dojo-props="label:'click me',onClick:function(){console.log('yes,clicked');}">  
  3.     </button>  

4、实例化非组件对象

dojo/parser一般用来实例化标签(例如Dijit组件)中的可视化元素,它也可以用来实例化非可视对象。dojo/parser解析配置信息作为第一个参数,node节点的引用作为第二个参数。这对基于dojo/_base/declare的非可视元素也是可行的。

有一个问题是,常规的对象不像Dijit组件一样有一个注册(Dijit组件在实例化时会根据承载元素的id值在dijit/registry中注册以便将来能获取到组件的引用),因此为了在实例化之后能够引用到这些对象,需要在全局区域创建一个引用。dojo/parse通过查找data-dojo-id属性来完成这个工作。 

 

[html] view plain copy
  1. <div data-dojo-id="myStore" data-dojo-type="dojo/store/Memory"  
  2.     data-dojo-props="data: [  
  3.         { name: 'Alabama', id: 'AL' },  
  4.         { name: 'Alaska', id: 'AK' },  
  5.         { name: 'Arizona', id: 'AZ' },  
  6.         { name: 'California', id: 'CA' },  
  7.         { name: 'Colorado', id: 'CO' },  
  8.         { name: 'Connecticut', id: 'CT' },  
  9.         { name: 'New York', id: 'NY' }  
  10.     ]"></div>  
  11. <select id="mySelect" name="state" value="CA"  
  12.     data-dojo-type="dijit/form/FilteringSelect"  
  13.     data-dojo-props="searchAttr: 'name', store: myStore"></select>  
Note:非可视化对象的引用时全局的,不会进行垃圾回收。因此在不需要这个对象之后需要移除,以防止内存泄露。

5、组件行为

处理组件的事件,我们最容易想到的是在JavaScript中编写一段代码来处理(例如调用组件的on方法)。实际上,也可以使用声明式方式来处理事件。

为了在标签中实现事件处理,我们需要使用”声明式脚本“来完成。声明是脚本可以让dojo/parser获取一段内联代码,并且在实例化对象时传入进去。我们来看一个例子

 

[html] view plain copy
  1. <div id="someDialog" data-dojo-type="dijit/Dialog"  
  2.         data-dojo-props="title: 'Hello World!'">  
  3.     <p>I am a dialog. That makes me happy.</p>  
  4. </div>  
  5. <button type="button" id="myButton" data-dojo-type="dijit/form/Button">  
  6.     <span>Click Me!</span>  
  7.     <script type="dojo/on" data-dojo-event="click">  
  8.         var registry = require("dijit/registry");  
  9.         registry.byId("someDialog").show();  
  10.     </script>  
  11. </button>  

声明式脚本支持的类型有dojo/on,dojo/aspect,dojo/watch,dojo/method,dojo/connect。

6、自动请求

dojo/parser在遇到一个类似MID的data-dojo-type值时,并且该模块并没有加载,dojo/parser在实例化这个对象之前会尝试去请求这个模块。这个特点非常好用,但是如果不小心的话它会影响你页面的性能。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM