创建基于模板的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。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值