——译自http://www.sitepen.com/blog/2010/07/01/creating-and-enhancing-dojo-classes/
原作者David Walsh
像所有一流的JavaScript工具包一样,Dojo致力于将类做得尽可能灵活,因为它知道不同的用户可能对一个类及其方法是如何工作的抱有完全不同的看法。幸运的是,Dojo提供了大量的方法使您能够继承或修改类。现在我们就来研究其中的一些方法,它们可以让你随心所欲地摆弄Dojo类。
创建Dojo类或子类的一个典型方法是用dojo.declare。dojo.declare把类注册到你所指定的名字空间中,并且能够继承任意数量的类(由第二个参数传入)。
以下代码展示了创建子类的基本写法:
以上代码创建的新类davidwalsh.Menu就是一个新的自定义Dojo类,它继承了dijit.Menu类的所有方法和属性,而且还添加了一个新的自定义属性以及一个自定义方法,可以用来做任何事情。既然我们已经知道如何创建子类了,那就让我们来写一个实用一点的davidwalsh.Menu吧:
davidwalsh.Mene是dijit.Menu类的增强版。它具有两个新的选项,并重载了一个dijit.Menu的方法。其目的在于提供一种在鼠标悬停时而非单击时打开弹出菜单项的菜单。
你可能在想,怎样在子类的方法里调用父类的方法呢?这也很简单:
可见,建立子类易如反掌。但如果你只需要修改一个现存的Dojo类,又该怎么做呢?答案是打补丁!
有时,继承一个现有的Dojo类并不是最好的选择(甚至有可能根本无法这样做)。你很可能处于这样一个境地,只能给现有的Dojo类打补丁,这时Monkey Patching就是最理想的选择。所谓Monkey Patching就是一个修改现有对象(在这里指Dojo类)的原型的过程。这一做法的优点有:
以下代码展示了Monkey Patching的模式:
现在我们来看一个实际例子。我最近正在使用FilteringSelect控件,我发现如果srcNode(也就是select元素)里的第一个option元素没有value属性(或者value为空字符串),那么这个元素的label就不会显示。这是一个非常奇怪的bug,并且肯定不是一个符合用户预期的行为。我所能做的就是给这个控件类的postMixInProperties方法打上补丁来修复这个问题:
这只是使用Monkey Patching的好例子之一。虽然打补丁可能看起来属于不太优雅的技术,但它的确是定制你手里Dojo包的一个必要方法。
Dojo.extend方法允许我们为类的原型添加新方法,从而为该类的所有实例提供这些方法。如果传给dojo.extend的某个方法在类中已经存在同名方法,那它将覆盖这个原有方法。
下面的例子展示了如果和扩展dijit.Menu类,从而使弹出菜单在鼠标悬浮在标签上时显示,而不是单击时。
注意到原有的onItemHover方法并没有被保存下来并在以后使用,而是整个原型都被重写了。因为我们正是要抛弃这个方法原来的功能。现在我们拥有了一个满足我们需求的dijit.Menu类,并且我们的Dojo包中的文件并没有受到干扰。
对于一个类,何时应该扩展何时应该补丁并没有一个硬性的规定。但我的确有几点建议:
扩展Dojo类是修复bug、增强Dojo内置类、以及避免重复代码的最佳途径。Dojo里没有任何限制,除了那些你强加给它的!