扩展 Dojo dijits 来创建自定义小部件
本文要介绍的内容是:当来自 Dojo 工具包的特定 dijit 无法全面满足您的需要,您需要创建自己的自定义小部件时,您可以怎么做。本文的最后提供了一个示例,其中包含一组需求和满足这些需求的方法,您将熟悉如何使用 dijit 和其他 Dojo 核心功能,以及如何声明自己的小部件。
简介Dojo Toolkit 是一个强大的 JavaScript? 库,支持 Web 开发人员使用面向对象的小部件,用最少的开发时间和工作量来创建富 Internet 应用程序。Dojo Toolkit 提供了 4 个包,它们分别是Dojo(核心)、Dijit(UI 框架)、dojox(dojo 扩展)和util。您可以原封不动地使用该工具包提供的功能,也可扩展它们并创建自己的小部件。提供的功能包括 DOM 操作、使用 AJAX 开发、事件、数据存储等。 Dijit(dojo 小部件)包是 dojo 自己的 UI 库,它包含一组 dojo 类,使开发人员能够以最少的工作创建功能丰富且强大的跨平台 Web 2.0 接口。这些 Dijit 小部件(或 dijit)支持一些易于操作的主题。这个包中的 dijit 示例包括按钮、文本字段、编辑器、进度条等。 举例而言,您可以使用这些 dijit 创建一个提交表单,其中包含用于名称、电子邮件地址和电话号码的文本字段,以及日期字段、复选框、按钮和验证,所有这些在几分钟即可完成,需要的 JavaScript 知识也极少。 提供的一个功能最丰富的 dijit 是 Calendar dijit,它支持在一个月的上下文中显示日历。用户可轻松地逐月、逐年导航,或者跳到同一年中任一个月,以选择特定的日期。 在开发富 Internet 应用程序 (RIA) 时,通常可以原封不动地使用 dijit。但是,有时您可能需要使用不同的样式(比如更改颜色或主题),或者需要进行更复杂的更改,其中可能需要结合使用某些功能、模板和样式更改。要满足这些需求,则需要从头创建一个新的自定义小部件,也可以创建一个扩展现有 dijit 的自定义小部件。 本文提供了一个练习,在这个练习中,您需要在自己的网站上使用 Calendar 小部件的不同变体。为了满足此需求,您需要创建一个新类。此练习使用了 Dojo version 1.7,提供了探索 Calendar dijit 的机会和以极少的改动重用现有 dijit 来节省开发时间的方式。您还会看到在 Dojo 1.7 中声明的一个新类的实用示例,探索一些 Dojo 基础功能,比如数据操作、hitch、发布和订阅等。 问题在此练习中,您将使用 Calendar dijit 的一个具有以下需求的自定义版本:
解决方法是创建一个自定义小部件,这个小部件通过使用 JavaScript 和 CSS 编辑 Calendar dijit 来开发。图 1 显示了应用上面需求之前(左侧)和之后(右侧)的 Calendar 小部件。 图 1. 标准 Calendar dijit 与自定义 Calendar 小部件的对比为此,您将需要创建 3 个文件:
图 2 显示了自定义小部件的文件结构和位置。您的起点是 index.html,它在本示例中充当了小部件的控制器。simple.css 文件将包含所有样式。 图 2. 文件结构回页首 创建小部件dijit 模板创建 3 个 JavaScript div 元素:一个用于日历,两个用于向前和向后逐月导航的箭头按钮(清单 1)。这些 div 将使用附加点 (data-dojo-attach-point) 进行引用。使用附加点比使用 id 更好,因为它使您能够在同一个页面上拥有同一个小部件的多个实例,无需担忧 id 冲突。 清单 1. dijit 模板<div class="CalendarArrow"> <div data-dojo-attach-point="calendarPreviousMonthButtonAP"></div> </div> <div class="CalendarDijit"> <span data-dojo-attach-point="calendarMonthOneAttachPoint"></span> </div> <div class="CalendarArrow"> <div data-dojo-attach-point="calendarFollowingMonthButtonAP"></div> </div> dijit 类根据应用程序需求,您需要定义以下变量:
JavaScript 函数首先修改以下样式表元素:
要满足其他需求,您需要修改 Calendar dijit 中的以下 3 个函数:
Calendar dijit 在页眉中附带了一个 monthDropDownButton。这个按钮显示了所有月份的列表,允许用户跳到任何月份。为了满足需求,您需要将 monthWidget 设置为 “disabled” 来禁用此按钮(清单 13)。 清单 13. 禁用 Calendar 页眉中的下拉按钮this.calendarInstance.monthWidget.set("disabled",true); 从实用性角度讲,您还需要隐藏箭头,使用户不会受到吸引而去单击它。为此,请添加定位您希望操作的元素的 CSS 类(清单 14)。 清单 14. 隐藏下拉按钮箭头的 CSS 类.AvailabilityCalendars .Calendars .CalendarDijit .dijitDropDownButton .dijitArrowButtonInner { visibility: hidden; } 接下来,使用 CSS 类隐藏去年和明年的 digit,禁止将它显示在底部(清单 15)。 清单 15. 在 Calendar 底部隐藏年份 digit 的 CSS 类.AvailabilityCalendars .Calendars .CalendarDijit .dijitCalendarPreviousYear,.dijitCalendarNextYear { padding: 1px 6px; visibility: hidden; } 您还将隐藏顶部的箭头,否则这些箭头允许用户逐月移动(清单 16)。 清单 16. 隐藏 Calendar 顶部的月份箭头的 CSS 类.AvailabilityCalendars .Calendars .CalendarDijit .dijitCalendarArrow { visibility: hidden; } 接下来,创建两个新按钮,以便允许用户导航月份。以编程方式使用 dijit/form/Button 创建这两个按钮。对于第一个按钮(后退),可以将标签设置为 “<<” 并修改 onClick 函数(清单 17)。onClick 的逻辑将包含在 goToPreviousMonth 函数中。 清单 17. 创建 dijit/form/bottom 的一个实例this.calendarPreviousMonthButton = new Button({ label: "<<",onClick: lang.hitch(this,function(){ this.goToPreviousMonth(this.calendarInstance); }) },this.calendarPreviousMonthButtonAP); 您希望在用户每次单击该按钮时,日历后退一个月。在 goToPreviousMonth 中,需要先将 currentFocusDate 更改为 currentFocusDate - 1 month,然后刷新日历的视图。最后,必须检查这是否要显示的最后一个月,如果是,则禁用该按钮。 使用 dojo/date/add 函数,它接受日期对象、间隔(字符串)和数量(整数)。对于您的情形,日期应该是 currentFocusDate 对象,间隔是 “month”,数量是 -1(清单 18)。 清单 18. 日历视图减去一个月this.currentFocusDate = dojoDate.add(this.currentFocusDate,"month",-1); calendarInstance.set("currentFocus",this.currentFocusDate); 设置日历的新视图,将 currentFocus 设置为新的日期值。(这将自动刷新日历并显示新视图)。 最后,请检查这是否是最后一个月的视图,方法是对比 currentFocusDate 与最小值边界;如果是最后一个月,则禁用后退按钮。另外,请检查您是否应启用了前进按钮(假如您禁用了该按钮,并且现在您离开了最大值边界)(清单 19)。 清单 19. 检查我们是否应该禁用新导航按钮if(this.isLastCalendarMonth(this.bookingWindowMinDate,this.currentFocusDate)){ this.calendarPreviousMonthButton.set("disabled",true); } if(!this.isLastCalendarMonth(this.bookingWindowMaxDate,this.currentFocusDate)){ this.calendarFollowingMonthButton.set("disabled",false); } 第二个按钮的工作原理相同。该标签将为 “>>”,onClick 调用 goToNextMonth,后者使用了同一个函数,但您添加了一个月(清单 20)。 清单 20. 控制移动到下一个月的按钮的函数goToNextMonth : function (calendarInstance){ this.currentFocusDate = dojoDate.add(this.currentFocusDate,1); calendarInstance.set("currentFocus",this.currentFocusDate); if(this.isLastCalendarMonth(this.bookingWindowMaxDate,this.currentFocusDate)){ this.calendarFollowingMonthButton.set("disabled",true); } if(!this.isLastCalendarMonth(this.bookingWindowMinDate,this.currentFocusDate)){ this.calendarPreviousMonthButton.set("disabled",false); } } 最后,清单 21 显示了应该在控制器类中的内容的示例,该类将进行相关调用,以便初始化您的新 customCalendar。 清单 21. 创建新的自定义日历小部件的实例的快照require(["myUtil/customCalendar","dojo/_base/connect"],function(myCalendar,connect){ var params = { "bookingWindowMinDate":"10/9/2011","bookingWindowMaxDate":"10/9/2012","selectedDate":"8/15/2012","onValueSelectedPublishIDString":"selectedValueID" }; var myTest = myCalendar(params); myTest.placeAt("nodeId","last"); connect.subscribe("selectedValueID",function(date){ //Do some processing console.log("I got: ",date); }); }); 如您所见,您创建了一个对象 params,其中包含需要传递给自定义日历小部件的值,并订阅了该频道。 更多函数您可能会发现其他一些函数和属性在此场景中也很有用:
这些自定义小部件需求的一种变体可能要求小部件显示多个日历,然后,在用户通过单击来查看下一个月时,要求两个日历都前进一个月(参见图 3)。这很容易完成,只需更改小部件变量来支持一个数组,而不是单个值变量。 图 3. 每个视图多个日历回页首
结束语通过组合 JavaScript 和 CSS 修改,很容易创建一个自定义小部件来更好地满足项目需求。本文演示了这种做法,使用 Dojo 1.7 声明了一个类,该类扩展了 Calendar dijit 并利用了一些 dojo 功能,比如日期操作、hitch、发布和订阅,以及其他一些基础 dojo 函数。希望您将能够应用这些步骤来扩展 Dojo dijit,并创建自己的新小部件。 回页首
下载
参考资料学习
获得产品和技术
讨论
信息来源:http://www.ibm.com/developerworks/cn/websphere/techjournal/1209_weller/1209_weller.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |