`
123003473
  • 浏览: 1064272 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Dojo之Widget标签开发

    博客分类:
  • dojo
 
阅读更多
Dojo widget就像是jsp中的自定义标签,通过学习开发widget标签来对其使用及其设计原理有更好的了解。本文主要是对Develop HTML widgets with Dojo一文的学习和翻译。

1.    Dojo widget的概念

正如上所述,dojo widget就像是jsp中自定义标签,只是dojo widget是在客户端使用的(本文中统一简称dojo widget为widget标签)。Widget标签已经脱离了传统的DOM模型结构,每个Widget标签都有唯一的widgetID,并且可以包含多个属性,而且可以包含子Widget标签。Widget共包含三个部分:

l         一个包含Widget标签逻辑的js文件,通过JavaScript DOM模型来处理可见的元素。

l         HTML模板文件,它提供基本的Widget HTML视图。当然如果模板很简单,完全可以在js文件中用字符类型替代。

l         Css样式文件,定义标签的样式,在js代码或者HTML模板文件中使用。

l         图片文件。

目录结构如下:

    dojo/src/widget ------------------------------------ js代码文件

     dojo/src/widget/templates ------------------------ HTML模板,Css样式文件

     dojo/src/widget/templates/images --------------- 图片文件



2.    Widget标签的使用

使用标准的Dojo Widget标签创建Button按钮,代码如下:
<html>
<head>
    <script type="text/javascript" src="js/dojo/dojo.js"></script>

    <script type="text/javascript">

       dojo.require("dojo.widget.Button");

    </script>

</head>

<body>

    <div dojoType="Button">Submit</div>

    <!--另一种使用Widget标签的方法-->

    <!--<dojo:button caption="Submit"></dojo:button>-->

</body>

</html>


3.    自定义Widget标签-HelloWorld

首先创建js/dojo/src/Widget/templates/HelloWorldTemplate.html,代码如下:

<div>

    HelloWorld

</div>


创建js/dojo/src/Widget/HelloWorl.js,代码如下:

dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld",

dojo.widget.HtmlWidget, 

    {    templatePath:dojo.uri.dojoUri("src/widget/templates/HelloWorldTemplate.html")

    }

);


注:所有用户自定义Widget标签都必须继承HtmlWidget。

创建测试文件HelloWorld.html,代码如下:

<html>

<head>

<script type="text/javascript" src="js/dojo/dojo.js"></script>

<script type="text/javascript">

    dojo.require("dojo.widget.*");

    dojo.require("dojo.widget.HelloWorld");

</script>

</head>

<title>Hello World Widget test</title>

<body>

    <div dojoType="HelloWorld"></div>

    <dojo:HelloWorld></dojo:button>

</body>

</html>


如果HelloWorldTemplate模板足够简单,可以使用templateString替换templatePath,修改后HelloWorld.js代码如下:
dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget, 

    {

       templateString: "<div>Hello World</div>"

    }

);


4.    自定义Widget标签属性

以上部分讨论了如何创建简单的自定义标签,下面需要给HelloWorld添加属性以及自样式,让其更像一个标准的Html标签。让HelloWorld标签的显示内容可以有用户定义,添加text属性就可以办到。修改后的代码如下:

HelloWorld.js

dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget, 

    {

       templateString: "<div>${this.text}</div>",

       text: ""//default value     

    }

);


注:自定义属性必须要设置默认值,否则会被Dojo忽略。而且Dojo会忽略DOM模型下的所有属性。

HelloWorld.html

<html>

<head>

<script type="text/javascript" src="js/dojo/dojo.js"></script>

<script type="text/javascript">

    dojo.require("dojo.widget.*");

    dojo.require("dojo.widget.HelloWorld");

</script>

</head>

<title>Hello World Widget test</title>

<body>

    <div dojoType="HelloWorld" text="you can set the text attribute"></div>

    <!--<dojo:HelloWorld text="you can set the text attribute"></dojo:button>-->

</body>

</html>


属性的处理

    处理属性的典型方法是postCreate()方法(稍候讨论),另一个方法是fillInTemplate()。许多Widget标签都是通过postCreate()方法来处理属性的,也有通过set方法。不同的是postCreate()方法是在标签创建时处理属性,而set方法是在运行时动态设置属性。

脚本片断

    在HEML模板文件中加入js代码并不是一个好的方法,但有时候却必不可少。在Dojo中可以使用${…}代码片断来获取属性值,正如上例中的${this.text}。

添加样式

    为了使Widget达到真正的功用,Dojo提供了定制css样式的功能,通过引用不同的自定义样式,可以方便的为应用改变显示效果。为HelloWorld标签添加样式,创建一个简单样式文件js/dojo/src/widget/templates/HtmlHelloWorld.css,代码如下:

.caption {

    font-family: Verdana;

    font-size: 10pt;

}


注:css类名必须是唯一的

修改HeolloWorld.js,代码如下:

dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget, 

    {

       templateString: "<div class=\"caption\">${this.text}</div>",

       text: "",//default value

       templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlHelloWorld.css") 

    }

);


5.    在js中使用Widget标签

本部分将说明如何用Dojo在js代码中使用HelloWorld标签,而传统的js方式已经不再适用。

传统方式操作Widget标签

    如果想在程序中动态改变text “Hello World”,你会试着用传统的js方式来实现,但是这样做是徒劳的。传统方式的代码如下:

<html>

<head>

<script type="text/javascript" src=" js/dojo/dojo.js"></script>

<script type="text/javascript">

    dojo.require("dojo.widget.HelloWorld");

</script>

</head>

<body onload="document.getElementById('HelloWorldTest').innerHTML='New

text';">

    <div id=" HelloWorldTest" dojoType="HelloWorld"></div>

</body>

</html>


这样的代码是没有任何效果的。下面就分析一下这段为何不会有作用。

A.      Body中的onload属性失效

Body中的onload属性与Dojo是不兼容的,Dojo已经在事件方法中包括了onload的事件。Onload事件在Dojo下使用,代码如下:

<html>

<head>

...

<script>

    dojo.addOnLoad(

       function(){

           alert("onload!");

       }

    );

</script>

</head>


B.      Dojo Widget标签与DOM element的区别

Dojo Widget标签已经不再是一个DOM element。Dojo创建Widget标签时,已经去掉所有DOM模式下的所有属性,除了Dojo认识的属性。例如,id已经演化成了widgetId。如果需要用传统的方式操作属性,必须通过修改模板文件来实现。如果需要获取ID,修改模板文件代码如下:


<div id="${this.widgetId}">Hello World</div>

Dojo方式操作Widget标签

    如果要用Dojo方式操作Widget标签,必须还要修改一些代码。修改后的HelloWorld.js代码如下:


dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget,

    {

       templateString: "<div dojoAttachPoint=\"domNode\" >${this.text}</div>",

       text: "",//default value

       // dynamic setters

       setHtml: function(htmlString) {

           this.domNode.innerHTML = htmlString;

       }     

    }

);



注:Dojo Widget标签使用attachment points来处理DOM element。在Dojo方式下,不需要id=”${this.widgetId}”,因为不会使用id来获取对象,而是使用attachment point。实际上attachment point是默认使用的。”domNode”是attachment points根元素

通过获取Widget标签对象实例,代码如下:   


<html>

<head>

<script type="text/javascript" src="js/dojo/dojo.js"></script>

<script type="text/javascript"> dojo.require("dojo.widget.HelloWorld");

    dojo.addOnLoad(function(){

       dojo.widget.byId("someID").setHtml("New text");

    });

</script>

</head>

<body>

    <div id="someID" dojoType="HelloWorld"></div>

</body>

</html>



通过使用dojo.widget.createWidget()方法动态创建HelloWorld实例,代码如下:


<html>

<head>

<script type="text/javascript" src="js/dojo/dojo.js"></script>

<script type="text/javascript">

    dojo.require("dojo.widget.HelloWorld");

    dojo.addOnLoad(

       function(){

           var newWidget = dojo.widget.createWidget(

           "HelloWorld", // widgetType

           {}, // widget attributes, for example {title: "Some Title"}

           dojo.byId("widgetPlaceholder") // reference to a DOM node that

           // will be REPLACED by new widget

           );

       }

    );

</script>

</head>

<body>

    <div id="widgetPlaceholder"></div>

</body>

</html>



6.    Widget标签嵌套HTML

本部分讨论如何实现Widget标签的嵌套

A.      嵌套静态HTML

正如前面提到的Dojo创建Widget标签时移除所有的DOM element。所以在Dojo移除之前,必须改变所要的DOM element。通过Dojo提供fillInTemplate()方法实现。此方法可以操作HTML DOM element和已经生成的Widget标签。实现改变静态HTML的HelloWorld.js代码如下:


dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget,

    {

       templateString: "<div dojoAttachPoint=\"domNode\">${this.text}</div>",

       text: "",//default value

       // dynamic setters

       setHtml: function(htmlString) {

           this.domNode.innerHTML = htmlString;

       },

      

       fillInTemplate: function(args, frag) {

           // Getting original HTML element

           var source = this.getFragNodeRef(frag);

           // Moving all children of original element to

           // the desired node of the new component

           while(source.hasChildNodes()) {

              var node = dojo.dom.removeNode(source.firstChild);

              this.domNode.appendChild(node);   

           }

           // Invoking original dojo fillInTemplate() method

        dojo.widget.HelloWorld.superclass.fillInTemplate.call(this, args, frag);

       }

    }

);



以上代码将HTML DOM节点转移到需要的地方,另一种实现方法是设置Widet属性isContainter为true。

动态添加嵌套HTML

    如何动态添加嵌套HTML实现方法要根据动态HTML的形式来决定:

l         嵌套HTML作为string提供,通过设置innerHtml属性实现。

l         嵌套HTML作为DOM节点提供,可以使用appendChild方法实现。

以上方式的实现代码如下:


dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget,

    {

       templateString: "<div>${this.text}</div>",

       text: "",//default value

       setHtml: function(html) {

           if (dojo.lang.isString(html)) {

              this.domNode.innerHTML = html;

           } else if (dojo.dom.isNode(html)) {

              // Cleaning whatever was there before

              dojo.dom.removeChildren(this.domNode);

              // Adding new element

              this.domNode.appendChild(html);

           } else {

              dojo.lang.assert(false, "setHtml called with incorrect type: " + (typeof html));

           }

       }     

    }

);



7.    Widget标签嵌套Widget标签

嵌套静态Widget标签

    有些情况下我们需要实现Widget标签的相互嵌套,例如Dojo TabContainer和Tree标签。要实现这样的Widget标签,你需要设置isContainer为true,而且要在模板中设置attachment point为”containerNode”,代码如下:


dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget,

    {

       templateString: "<div dojoAttachPoint=\"containerNode\">${this.text}</div>",

       text: "",//default value

       isContainer: true

    }

);



这种实现是依赖Dojo的,如果需要实现更加复杂的,必须要操作postCreate方法中的Children数组,数组中存了所有嵌套的静态Widget标签。

测试代码:


<html>

<head>

<script type="text/javascript" src="js/dojo/dojo.js"></script>

<script type="text/javascript">

    dojo.require("dojo.widget.Button");

    dojo.require("dojo.widget.HelloWorld");  

</script>

</head>

<title>Hello World Widget test</title>

<body>

    <div dojoType="HelloWorld" text="   ad you can set the text attribute">

       <div dojoType="Button">Submit</div>

    </div>

    <!--<dojo:HelloWorld text="you can set the text attribute"></dojo:button>-->

</body>

</html>



复杂应用请参考Dojo TabContainer和Tree标签。

动态添加Widget标签嵌套

    动态添加Widget标签嵌套,需要在HelloWorld.js中实现addChild()方法,重写addChild()方法中还要调用父类的addChild()方法。实现动静态添加Widget标签嵌套的代码如下:


dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget,

    {

       templateString: "<div dojoAttachPoint=\"titleNode\">${this.text}" +

                       "<br/><div dojoAttachPoint=\"containerNode\">"

                     + "</div></div>",

       text: "",//default value

       isContainer: true,

       postCreate: function() {

           // adding statically

           for(var i in this.children) {

              this._addRow(this.children[i]);

           }

       },

       addChild: function(child, overrideContainerNode,

           pos, ref, insertIndex) {

           this._addRow(child);

           dojo.widget.HelloWorld.superclass.addChild.call(

           this, child, overrideContainerNode);

       },

       _addRow: function(component) {

           this.titleNode.appendChild(

           document.createTextNode(component.widgetType));

           this.titleNode.appendChild(

           document.createElement("br"));

       }

    }

);





注:经测试发现,即使不实现addChild方法,同样可以动态添加Widget标签嵌套,但是在HtmlWidget类中也没有找到addChild方法的实现,这里有待进一步研究。

测试代码:


<html>

<head>

<script type="text/javascript" src="js/dojo/dojo.js"></script>

<script type="text/javascript">

    dojo.require("dojo.widget.Button");

    dojo.require("dojo.widget.Checkbox");

    dojo.require("dojo.widget.HelloWorld");

    dojo.addOnLoad(function(){

       var button = dojo.widget.createWidget("Button",

                         {caption: "Submit"});

       dojo.widget.byId('someID').addChild(button);

       var checkbox = dojo.widget.createWidget("Checkbox");

       dojo.widget.byId('someID').addChild(checkbox);

    });

</script>

</head>

<title>Hello World Widget test</title>

<body>

    <div dojoType="HelloWorld" id="someID"></div>

    <!--<dojo:HelloWorld text="you can set the text attribute"></dojo:button>-->

</body>

</html>



8.    Dojo事件处理

本部分主要介绍使用Dojo的方式处理事件,在阅读本部分之前,最好先了解Dojo事件系统。首先需要在模板中定义dojoAttachEvent=”eventName: eventHandlerMethod;”属性。eventName是标准的DOM事件名称(例如:onClick),eventHandlerMethod则为事件调用函数。修改后的代码如下:


dojo.provide("dojo.widget.HelloWorld");

dojo.require("dojo.widget.HtmlWidget");

dojo.widget.defineWidget("dojo.widget.HelloWorld", dojo.widget.HtmlWidget,

    {

       templateString: '<div dojoAttachPoint="domNode" dojoAttachEvent="onClick:onClickHandler;">Click here</div>',      

       onClickHandler: function(e) {

           alert("clicked in onClickHandler");

           this.onClick(e);                  

       },

       onClick:function (e) { //for dojo.event.connect

       }

    }

);



注:可以在标签中预定义某一事件的函数,如上例中的onClickHandler,同时也可以预留接口让用户绑定自定义函数。

测试代码:


<html>

<head>

<script type="text/javascript" src="js/dojo/dojo.js"></script>

<script type="text/javascript">

    dojo.require("dojo.widget.HelloWorld");

    function HelloWorld_onClick() {

       alert("Node clicked in HelloWorld_onClick");

    }  

    dojo.addOnLoad(function(){

       var hello = dojo.widget.byId("someID");

       dojo.event.connect(hello, 'onClick', 'HelloWorld_onClick')

    });

</script>

</head>

<title>Hello World Widget test</title>

<body>

    <div dojoType="HelloWorld" id="someID"></div>

</body>

</html>



总结:

通过对本文的学习,初步了解了Dojo的Widget标签的简单使用和如何实现自定义Widget标签。

【转载地址】http://27091497.blog.163.com/blog/static/11806250200772210458268/
分享到:
评论

相关推荐

    Dojo之Widget标签开发 - 我为人人,人人为我 - BlogJava

    本文主要探讨的是在Dojo框架下进行Widget标签开发的技术细节,旨在帮助开发者更好地理解和利用Dojo构建可重用、模块化的Web组件。 首先,我们要了解什么是Widget。在Dojo中,Widget是UI组件的基础,它封装了HTML...

    基于 HTML5 的 Dojo Widget 开发

    ### 基于HTML5的Dojo Widget开发 #### 一、引言 随着Web技术的不断发展,HTML5已经成为新一代的Web标准,它不仅增强了对JavaScript的支持,还引入了许多新特性,例如音频视频标签、离线存储、Web Socket以及矢量...

    利用dojo进行客户端开发过程

    在客户端开发中,Dojo ...Dojo 提供了丰富的 API 和 widget 支持,使得开发高效且易于维护的 Web 应用成为可能。通过深入理解 Dojo 的核心概念和用法,开发者可以充分利用其强大功能,构建出高性能、跨平台的应用程序。

    DOJO API 中文参考手册,附加注解实例(精心重新排版DOC文档)

    例如,设置isDebug为true可以在开发过程中开启调试模式,baseScriptUri可以指定Dojo脚本的基础URI,parseWidgets控制是否自动解析页面中的Widget标签。通过正确配置djConfig,开发者能更好地优化Dojo的性能和功能。 ...

    DOJO 中文 开发手册

    Widget支持自定义样式和事件处理,通过简单标签即可在页面中使用。 **常用包介绍** Dojo 1.1.1 包含Dojo、Dijit和DojoX三个一级命名空间: 1. **Dojo**:核心功能包,提供基础API和服务。 2. **Dijit**:包含所有...

    DOJO客户端性能优化

    Dojo是一个强大的JavaScript工具包,旨在加速Web应用程序的开发,尤其在处理复杂的交互和动态功能时。为了优化DOJO客户端的性能,以下是一些关键策略: 1. **编译合适的dojo文件**:由于DOJO框架庞大,包含许多不必...

    dojo学习...........

    2. 引入Dojo核心库:通过`&lt;script&gt;`标签引入`dojo.js`,这是Dojo的基础文件,可能已经包含了部分常用模块。 3. 声明需要使用的模块:使用`dojo.require()`来引入所需的包或模块,确保它们在运行时可用。 Dojo为了...

    使用_Dojo_Mobile_为_iOS_智能终端开发_Native-like_Web_应用

    随着移动互联网技术的迅猛发展,为iOS等智能终端开发应用程序成为了开发者的重要技能之一。iOS,作为Apple公司推出的移动操作系统,已经广泛应用于iPhone、iPod Touch、iPad等设备中。iOS应用开发主要有原生应用...

    DOJO—API—中文参考手册

    - **parseWidgets**:是否自动解析页面中的Widget标签。 - **searchIds**:搜索标识符列表,用于快速定位DOM元素。 - **baseRelativePath**:基础相对路径,用于确定资源的相对位置。 - **libraryScriptUri**:库...

    DOJO中文手册,非常全面

    - **模块化**:根据所需功能的不同,DOJO提供多种版本,如AJAX版本、Widget版本、Event and I/O版本等。 - **自定义核心文件**:用户可以根据需求定制自己的核心代码文件,仅包含所需的模块,从而提高加载效率。 ##...

    DOJO_API_中文参考手册 附加注释实例

    - Widget支持自定义样式表和内部事件处理,用户通过简单的HTML标签即可使用。 - Dojo提供了丰富的Widget组件,如表格、树、菜单等,方便开发者构建用户界面。 3. Dojo、Dijit和DojoX的包和功能: - Dojo核心功能...

    dojo组件资料

    通过学习这些核心概念,你可以更好地理解和使用Dojo组件,同时,结合提供的“DojoToolbox.air”,你将获得一个桌面环境下的开发辅助工具,使你的Dojo开发之旅更加顺畅。对于源码分析和工具使用的深入探究,将进一步...

    Dojo1.rarDojo1.rarDojo1.rarDojo1.rar

    【标签】:Dojo1.rar 【压缩包子文件的文件名称列表】:精通 Dojo.000 本文将深入探讨Dojo框架的核心概念和关键特性,帮助你精通这个强大的工具集。 ### 1. Dojo简介 Dojo 是一个开源的JavaScript工具包,始于...

    DOJO中文学习手册2019-12-11.docx

    Dojo还在尝试创建一种新的标签语言DojoML,期望在不改变DojoML和JavaScript语法的情况下,通过不同的渲染方式展现数据,比如SVG或桌面应用。DojoML解析器能接受HTML和SVG输入,从而构建降级响应式应用程序。 在AJAX...

    dojo 之基础篇

    - **`&lt;button&gt;` 标签**:使用 Dojo 的 widget 功能来创建一个按钮,通过设置 `dojoType` 和 `widgetId` 属性,指定了这是一个 Dojo 的 Button 类型的小部件,并为其分配了一个 ID。 2. **JavaScript 部分** ```...

    Ajax Development With Grails Dojo

    - **熟悉Grails与Dojo的集成**:包括使用Dojo的标签、库和抽象层进行开发。 - **深入控制器与动作**:学习如何使用控制器处理Ajax请求,掌握`render()`方法、构建器和模板等关键概念。 - **获取实用技巧和资源**:...

    dojo例子之布局管理

    Dojo 是一个强大的JavaScript工具库,它为Web开发提供了丰富的功能,包括UI组件、数据管理、AJAX交互以及模块化开发等。在这个“dojo例子之布局管理”中,我们将深入探讨Dojo如何帮助我们构建具有高效布局的网页应用...

    dojo study keep moving

    ### Dojo 学习知识点详解 #### 一、Dojo 概述 Dojo 是一个功能强大且灵活的开源 ...以上是对 Dojo 学习笔记中提到的核心概念和操作方法的详细介绍,希望能帮助你更好地理解和掌握 Dojo 这一强大的前端开发框架。

    dojo学习笔记(web编程必备)

    - **加载Dojo核心库**:通过`&lt;script&gt;`标签引入`dojo.js`,这是Dojo的核心文件,通常经过压缩,如果需要查看源码,可以使用未压缩的`dojo.js.uncompressed.js`。 - **声明所需模块**:使用`dojo.require()`来导入...

Global site tag (gtag.js) - Google Analytics