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读取文档和实例化组件。看个例子:

<button type="button" id="myButton" data-dojo-type="dijit/form/Button">
    <span>Click Me!</span>
</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。

<script type="text/javascript" src="lib/dojo/dojo.js"
    data-dojo-config="async: true"></script>
<script type="text/javascript">
    require(["dojo/parser","dojo/ready","dijit/form/Button"],function(parser,ready){
        ready(function(){
            parser.parse();
        });
    });
</script>

3、配置对象

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

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

<button id="btn1" data-dojo-type="dijit/form/Button"
            data-dojo-props="label:'click me',onClick:function(){console.log('yes,clicked');}">
    </button>

4、实例化非组件对象

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

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

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

5、组件行为

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

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

<div id="someDialog" data-dojo-type="dijit/Dialog"
        data-dojo-props="title: 'Hello World!'">
    <p>I am a dialog. That makes me happy.</p>
</div>
<button type="button" id="myButton" data-dojo-type="dijit/form/Button">
    <span>Click Me!</span>
    <script type="dojo/on" data-dojo-event="click">
        var registry = require("dijit/registry");
        registry.byId("someDialog").show();
    </script>
</button>
声明式脚本支持的类型有dojo/on,dojo/aspect,dojo/watch,dojo/method,dojo/connect。

6、自动请求

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

相关文章

参考博客:https://blog.csdn.net/blog_szhao/article/details/50220181           https://doj...
我有一个包含多个字段的Dojo DataGrid.我目前正在设置查询一次搜索一个字段,如下所示: grid.setQuery(...
我正在使用JsonRestStore,但想为它添加一个自定义Accept标头.最好的方法是什么? 这与dijit.layout.Con...
我需要选择一个给定其URL的链接节点.使用属性选择器的效果非常好,除了少数几个url有tilda的情况.我无法...
我正在尝试使用Dojo JSONREST的增强网格,我遇到了一些问题. 我一直在寻找一些例子,但无法弄清楚如何做我...
如何根据一些运行时参数隐藏dgrid(gridFrom Html)中的完整列? 让我们说如果参数的值为true我应该能够显...