`

创建基于模板的Widget(译)

 
阅读更多

在本教程中,你将学习关于Dijit‘s模板混合的重要性和如何用模板去快速创建你自己自定义的widgets.

准备开始

Dijit’s的_Widget和_WidgetBase胃创建widgets提供了一个极好的基础,但是_Templated的混合特性是Dijit真正出众的地方。用_Templated,你可以快速创建高度可维护性、快速维护性和易操作的widgets。

_Templated的基础概念是足够简单的:它允许开发者去创建一个带有一些小扩展的小HTML文件,在运行时加载这个HTML文件作为一个字符串,它被模板widget的所有实例重用。


让我们穿行_Templated所定义的(为什么),然后用它的功能从头开始建造一个widget。

注意:_Templated拟被用作一个mixin,并不直接继承它。在基于类的语法中,这意味着它更像一个接口而非类(虽然与JavaScript,塔门之间的差异是模糊的)。

_Templated所提供的

对工作开发者来说,把_Templated混合进一个widget定义,为你的widget提供了如下的附属属性:

templateString,//  a string representing the HTML of the template

templatePath://  a URL pointing at a file to be used as a template

widgetsInTemplate://  a Boolean indicating whether or not child widgets

                //  are defined in the template

这3个属性看似简单——毕竟,这么大的力量怎么可能来自如此一点?这个答案存在于

_Templated加入到你widget定义中的其他方法。

覆盖方法

除上述的属性之外,_Templated覆盖了定义在Dijit'swidget架构中的三个方法:buildRendering,destroyRendering和startup.这三个方法控制模板的解析和填充(buildRendering),正确的销毁widget的DOM(destroyRendering)和确保模板中的任何子widget正确启动。

注意:因为所有这三个方法对于模板处理过程是至关重要的,如果你在你的自定义代码中重写了他们中的任何一个——确保在你的重写方法中

通过增加this.inherited(arguments)来包含对于父版本的调用。

_Templated

为了确保你自定义的widget是"templatable",所有你需要做的是为你的widget增加"dijit/_Templated"作为类声明数组的第二个参数。

例如,一个SomeWidget的widget可能会像这样声明:


require(["dojo/_base/declare", "dijit/_Widget", "dijit/_Templated", "dojo/text!./templates/SomeWidget.html"],
        function(declare, _Widget, _Templated, template) {
     
    return declare("example.SomeWidget", [_Widget, _Templated], {
        templateString: template
        //  your custom code goes here
    });
     
});

注意:Dijit依附一个标准,通过在JavaScript声明的同一层级创建一个叫做"templates"的单独目录——我们建议你在你自己的代码中遵循此标准。

注意在上面我们的声明中,我们用templateString属性与一个模板相连,此模板通过dojo/text!{path}来加载。这是设置引用到你模板文件的推荐方式,因为它确保了文件能够被异步加载和当创建一个Dojo工具箱的构建时能适度整合。

现在我们基于模板来建立我们的widget声明。让我们写一个模板和讨论一些特别在他们中可用的hooks。

写模板

一个模板就是一个HTML文档碎片,在里面你定义一个DOM结构,伴随任意特别的”hooks“,把事物返回到你的widget声明里。在我们投入到这些hooks中的每一个之前,看一个快速的例子,在一个模板里变量替换如何发生。这里是我们的SomeWidget的假想模板:


div class="${baseClass}" data-dojo-attach-point="focusNode" data-dojo-attach-event="ondijitclick:_onClick" role="menuitem" tabindex="-1">
    <span data-dojo-attach-point="containerNode"></span>

</div>

在简单的同事,这个模板展示了Dijit模板系统三个最重要的方面:变量替换、附着点、事件附着

注意:当你定义一个模板的时候,只能有一个根节点定义(就像XML文档)。在顶层的多节点是不被允许的。

变量替换

一个模板通过使用简单的变量占位符语法把值设置在提供的DOM上,看起来像这个:
${property}
这个变量的名字是你的widget声明里的任何属性或者字段定义。上述的例子使用了baseClass属性(在任何widget都是可用的),但是自定义字段也是一样的使用方法—例如,我们在我们的SomeWidget里定义了一个属性叫 foo,我们可以简单的使用${foo}在我们的模板里。如果这个属性碰巧是一个对象的引用,如果你想使用这个对象里的属性值,你可以很容易的做这个通过正常的对象引用符号:
${propertyObject.property}

为了预防_Templated中字符串的避免引号,可以再变量名称钱放置"!",像这样:
${!property}
注意:自从Dijit1.5起,在模板里使用变量替换仅仅为那些在widget生命周期中不会改变的那些值。如果你期望在应用程序编程阶段去设置值,我们建议你用widget的postCreate方法去设置任意的变量。

附着点

Dijit的模板系统有一个特别的属性,它可以再你的模板中找到,叫做attach point——用HTML5数据属性语法来实现。一个附着点告诉模板提供者,当你用data-dojo-attach-point来定义一个DOM元素用时,作为你widget的一个属性去设置那个属性值,这个属性就作为DOM元素创建的一个引用。例如:对于SomeWidget,模板定义 了两个DOM元素。在你的代码里,主元素可以通过属性focusNode引用,内部的span元素可以通过属性containerNode 来引用。

一般的,你模板的根节点变成你widget的domNode属性,因此一般在定义里不需要包含一个附着点属性。然而,有时候,在Dijit里这么做是允许跟节点也可以和其他子系统进行作用,诸如Dijit的焦点管理。

containerNode附着点

 

Dijit也定义了一个“magical”附着点叫containerNode,一个container node的基本概念:如果一个widget是声名式创建的,则为任何额外标记的放置提供空间。例如,对于SomeWidget给定的模板,我们在标记里可以这样用:

 

<div data-dojo-type="example.SomeWidget">
    <p>This is arbitrary content!</p>
    <p>More arbitrary content!</p>

</div>

当Dojo解析器横穿文档时,它将会发现我们的例子widget并实例化,作为实例的一部分,widget里的任何

标记将会被追加到containerNode。所以当widget的启动完成时,作为结果的DOM将会看起来像这样:

 

<div class="someClass" role="menuitem" tabindex="-1">
    <span>
        <p>This is arbitrary content!</p>
        <p>More arbitrary content!</p>
    </span>
</div>

 

注意:为了简短,我们移除了一些自定义的HTML5属性。Dijit在提供模板的时候不会移除他们。

同时,也要意识到如果你在主标记中嵌入了其他的widget定义,并且你的widget有一个containerNode附着点

,在这个container node里的任何widgets都将会被实例化。例如,当组装一个应用程序的时候,下面是一个典型的场景:

 

<div data-dojo-type="example.SomeWidget">
    <p>This is arbitrary content!</p>
    <div data-dojo-type="dijit.form.Button">My Button</div>
    <p>More arbitrary content!</p>

</div>

事件附着

除了附着点之外,Dijit模板系统给你提供了一个把native 的DOM事件附着到你自定义widget里方法的方式。它通过使用

HTML5数据属性data-dojo-attach-event来实现。这是一个逗号隔开的键/值对(用冒号分割)字符串,键是附着控制器的native DOM事件,值是当事件发生时,你的widget需要执行的方法的名字。如果仅有一个单一的事件需要去控制,忽略最后的逗号。例如,这个是定义在Dijit MenuBarItem里的dojo-data-attach-event属性:

data-dojo-attach-event="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick"


注意:我们定义在我们例子模板中的事件,ondijitclick,是由Dijit自己设置的一个修饰handler,支持额外的东西,一个普通的onclick事件

不需要捕获。一般来说,你可以在任何你想正常使用onclick的地方使用它


当你widget已经实例化,DOM碎片已经从你的模板创建,Dijit模板系统将会贯穿任意的事件定义,自动地从作为结果的DOM和你的widget对象中连接这些事件(用connect)——使得它难以置信的简单去连接你的可视化表现和你的控制代码。另外,当这些事件控制器fired时,一般的,由native DOM事件机制传递的同样的参数将会沿着你的widget控制器传递,因此你有充分的访问报告的权利。

 

widgetsInTemplate 属性

最后,Dijit模版系统允许你通过widgetsInTemplate属性的使用,从模板去创建更复杂的widget。这个属性(缺省是 false)告诉模板系统你的模板有其他的widget,并且当你的widget实例化的时候,实例化他们。


例如:让我们修改我们的声明和我们的模板,让它总是包含一个Dijit button:
For example, let's modify both our declaration and our template to always include a Dijit button:
require(["dojo/_base/declare", "dijit/_Widget", "dijit/_Templated", "dojo/text!./templates/SomeWidget.html"],
        function(declare, _Widget, _Templated, template) {
     
    return declare("example.SomeWidget", [_Widget, _Templated], {
        templateString: template,
        widgetsInTemplate: true
        //  your custom code goes here
    });
     
});
 
//   our template
<div class="${baseClass}" data-dojo-attach-point="focusNode" data-dojo-attach-event="ondijitclick:_onClick" role="menuitem" tabindex="-1">
    <div data-dojo-type="dijit.form.Button" data-dojo-attach-point="buttonWidget">
        My Button
    </div>
    <span data-dojo-attach-point="containerNode"></span>

</div>


注意:在我们修改的模板里,连同button的标记,我们已经增加了一个叫做

buttonWidget 的附着点。这个是Dijit附着点系统的一个额外的bonus;因为在讨论之中定义是一个widget,增加到我们widget的属性—myWidget.buttonWidget——将会是真实button widget的一个引用,并不是DOM元素的引用。这允许你在简单的构造块之外创建uber-widgets,如此的一个widget被认为是一个email清单,一个有事先预置widget的工具栏,等等更多。    

除非你有明确的需要在你的模板里定义widget,否则把widgetsInTemplate设置为false,或者简单的在你的widget定义里里不包含它。塔导致的额外效果可以影响widget的性能,如果过分使用,你的应用程序性能也会受影响。

 结论

 

在这个指南里,我们学习了由混合_Templated所实现的Dijit强大的模板系统,你如何使用这个系统去快速的创建你自己定义的使用在你应用程序中的widget。我们已经回顾了模板系统的附着点和事件附着如何让你快速的绑定DOM元素到你的代码,如何替换模板中的值——也有在你的widget模板中如何去包含其他的widget以创建uber-widgets。

这个是本人第一次翻译,肯定存在诸多理解不正确的,恳请各位读者在阅读的过程中,提出宝贵的建议,非常感谢!!!

分享到:
评论

相关推荐

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

    1. **dojo.declare**: 这是Dojo用于创建类的函数,它允许我们定义一个基于其他类的新类。在Widget开发中,通常会声明一个新的Widget类,继承自Dojo的基础Widget类,如`dijit/_WidgetBase`。 2. **templateString或...

    基于Flutter设计的UI模板动态化框架

    Flutter UI模板动态化框架是基于Dart语言构建的,它利用了Flutter的Widget体系结构,使得创建和更新UI变得极其灵活。在Flutter中,Widget是构建用户界面的基本单元,它们可以组合起来形成复杂的视图,并且可以在运行...

    前端开源库-jquery-widget-compiler

    【前端开源库-jquery-widget-compiler】是一款专为前端开发者设计的工具,它基于jQuery库,旨在帮助开发者创建和编译自定义的UI小部件。这个项目的核心目标是将jQuery插件开发体验提升到一个新的层次,引入了类似Web...

    Python-一个cookiecutter模板用于创建一个自定义Jupyter小部件项目

    压缩包中的`widget-cookiecutter-master`可能表示模板的主分支或版本。在解压后,你可能会看到如下文件和目录: - `README.md`: 项目的介绍文件,包含如何使用和安装的说明。 - `setup.py`: Python项目的配置脚本,...

    Widget Creation Script For Photoshop CS 英文版

    5. **自定义和扩展**:通过掌握Scripting,用户不仅可以按照预设的模板创建Widget,还可以根据项目需求进行个性化定制。例如,增加动画效果、调整界面布局、嵌入第三方API等。 6. **学习资源**:除了提供的“Widget...

    基于PHP的zblog仿娱乐网CMS模板.zip

    【标题】"基于PHP的zblog仿娱乐网CMS模板.zip" 涉及的主要知识点是PHP编程语言以及zblog CMS系统。PHP是一种广泛使用的开源服务器端脚本语言,尤其适用于Web开发,能够嵌入到HTML中,为网页添加动态功能。Zblog是一...

    eoeAndroid特刊04_Android widget

    - **选择合适的项目类型**:在Android Studio中新建项目时,可以选择包含Widget模板的项目类型。 - **添加必要的权限**:根据Widget的功能需求,可能需要在AndroidManifest.xml中添加相应的权限声明。 - **创建...

    利用Flutter创建食品店App的UI模板精彩解决方案

    总结,利用Flutter创建食品店App的UI模板是一个涉及众多技术点的过程,从基本的Widget布局到复杂的业务逻辑处理,都需要开发者具备扎实的Flutter知识和良好的编程实践。通过不断学习和实践,我们可以构建出功能完善...

    Android2.2 widget小程序

    - 使用Eclipse IDE,创建一个新的Android项目,选择"Android Application Project"模板。 - 在res/layout目录下创建XML布局文件,定义小部件的界面结构。例如,包含两个ImageView用于显示不同的机器人头像,以及一...

    flexviewer widget自由移动代码

    在FlexViewer应用开发中,创建自定义的可自由移动的Widget是提高用户体验的重要一环。FlexViewer是一款基于Adobe Flex技术的轻量级GIS(地理信息系统)应用框架,它允许开发者构建交互式的地图应用。本教程将详细...

    ShopEx_V4.8模板制作手册

    4. **恢复默认状态**:基于theme.xml还原模板到初始状态。 5. **模板配置**:在“编辑模板”中进行可视化编辑,包括添加、删除和修改挂件。 **框架(Frame)**: - 框架决定页面布局和挂件区域,例如两栏或三栏布局...

    QT-main.cpp-widget.h\.cpp

    以上就是基于Linux的QT开发环境搭建的基本步骤,以及如何创建一个简单的带有窗口和按钮的应用。通过不断的实践和学习,你可以掌握更复杂的QT GUI编程技术,如布局管理、信号与槽机制、自定义控件等,从而构建功能...

    JavaShop模板制作手册.doc

    JavaShop是一款基于Java技术的电商系统,其模板制作手册详细介绍了如何构建和配置页面展示。手册主要包括两大部分:模板解析机制和挂件使用说明。 **模板解析机制** 1. **URL-模板文件映射**:JavaShop的页面显示...

    Flex_Viewer解析-----结构(2).doc

    在类的构造函数中,BaseWidget添加了一个“creationComplete”事件监听器`initWidgetTemplate`,在Widget创建完成后初始化模板,将Widget的属性如标题、图标等设置到模板上,从而在界面上显示出来。 当Widget被创建...

    Laravel开发-laravel-widgets .zip

    创建Widget时,可以创建一个新的类继承自预定义的Widget基类,比如`useful\widgets\Widget;`。在类中定义渲染方法,包含HTML和Blade代码。然后在视图中调用Widget类的方法来显示Widget。 6. **优点**: - 代码...

    Android-Widget-Event-Handling

    同时,文档还提到了“Using an anonymous inner class”和“Using a named inner class”,这两种是定义局部类的方法,它们在事件处理中提供了便捷的方式来创建一次性使用的事件处理器。 文档中还涉及了“Using the...

    基于ESRI Flex Viewer框架的ArcGIS Server开发

    该框架是基于Adobe Flex技术,结合ESRI的ArcGIS Server,为开发者提供了一种高效、灵活的方式来创建功能丰富的地图应用。 **Flex Viewer框架结构** Flex Viewer框架主要由以下几个部分组成: 1. **Menu Control**...

    widget

    "widget-master"可能是某个基于PHP的Widget开发项目的主分支。在这样的项目中,我们可能会看到以下结构: 1. **源代码文件**:包括Widget的PHP类文件,每个类对应一个特定的Widget功能。 2. **视图文件**:通常使用...

    vaadin-archetype-widget-7.1.5.zip

    【标题】"Vaadin Archetype Widget 7.1.5" 是一个用于创建Vaadin应用程序的模板工具,它属于Vaadin框架的一个版本。Vaadin是一个流行的Java Web开发框架,它允许开发者构建用户界面,无需处理复杂的JavaScript和HTML...

    实用的ecshop模板开发资料

    ECShop是一款基于PHP语言开发的开源电子商务系统,其模板开发对于进行二次开发至关重要。了解ECShop的文件结构有助于我们更好地理解和定制其外观和功能。在ECShop中,主要的文件夹包括: 1. `admin`:后台管理界面...

Global site tag (gtag.js) - Google Analytics