dojo如何覆盖dijit类方法

Big*_*der 2 javascript dojo dom-events

我需要覆盖Tree.js中的onClick方法.是否有任何常见的方法来覆盖dojo/dijit类方法?

Ken*_*iro 10

我有点困惑,因为你已经在你发布最后一个问题中这样做.

你有几个选择,这取决于你想做什么.

Clobbering方法存根

对于类似真实存根的情况onClick,它可能就像在窗口小部件实例上破坏该方法一样容易.

编程方式:

var myWidget = new dijit.Tree({
    ...,
    onClick: function(item, node, evt) {
        /* handler code here */
    }
};
Run Code Online (Sandbox Code Playgroud)

或者以声明的方式(这与您在上一个问题中所做的完全相同):

<div dojoType="dijit.Tree" ...>
    <script type="dojo/method" event="onClick" args="item,node,evt">
        /* handler code here */
    </script>
</div>
Run Code Online (Sandbox Code Playgroud)

连接到方法调用

在其他情况下,也许您需要在调用给定方法时执行某些操作,在这种情况下,您可以使用窗口小部件的connect方法(dojo.connect当窗口小部件被销毁时,这是一个更好的版本将自动清除).在这种情况下,你可以做这样的事情:

编程方式:

//execute the given function whenever myWidget's onClick method is called
myWidget.connect(myWidget, 'onClick', function(item, node, evt) {
    /* handler code here */
});
Run Code Online (Sandbox Code Playgroud)

声明地说,这可以与上面非常相似,除了代替type="dojo/method",确保你使用type="dojo/connect"

<div dojoType="dijit.Tree" ...>
    <script type="dojo/connect" event="onClick" args="item,node,evt">
        /* handler code here */
    </script>
</div>
Run Code Online (Sandbox Code Playgroud)

请注意,当您像这样连接时,您的代码将您要连接的调用方法之后执行.如果您之前需要做某事,那么您最好的选择可能就是dojo.declare您自己对小部件的扩展.如果你需要走那么远,我会详细说明,但我认为你可能会选择上述选项之一.

编辑#1:连接点(没有双关语......哦,哎,是的)

因为似乎我的评论添加到我的答案,原来的问题在某种程度上还不够清楚,这里是一个代码块修改基于简单的两个步骤在这一问题的原始代码完全相同,因为我在评论解释.唯一微小的皱纹是传递给的论点_onClick略有不同.

<div dojoType="dijit.Tree" ...>
    <script type="dojo/connect" event="_onClick" args="node,evt">
        /* handler code here. In this case, item is accessible via node.item */
    </script>
</div>
Run Code Online (Sandbox Code Playgroud)

此解决方案可能感觉有点次优,因为它涉及连接到建议为私有的方法.然而,无论是否openOnClick真实,它都应该起作用.如果你确信你将不得不openOnClick设置true,你可能会写一个函数,然后将其连接到两个onClickonOpen代替(既获得通过的项目,则节点).

编辑#2:常用功能,以编程方式连接

为了回答你的后续问题,我想以相反的顺序解决它们 - 因为如果你有兴趣以编程方式连接,它实际上会让另一个问题更容易回答.

首先,回答你的connect问题:你肯定不想使用dojo.byId,因为那不是给你Tree小部件,它给你一些与小部件相关的DOM节点(可能是最顶层的).作为一般规则,dojo方法对东西一无所知dijit.

你想做什么,就是我上面提到的.在这里,它是根据您尝试的代码应用的.还要注意,它onClick有一个大写字母C - 另一个通用规则:小部件事件使用驼峰式表示法,作为区分它们的方法,而不是普通的DOM事件.

var mytree = dijit.byId("mytree");
mytree.connect(mytree, "onClick", function(item) {
    /* ... */
});
Run Code Online (Sandbox Code Playgroud)

现在,采取更进了一步,并解决您的相关咨询,如果你要绑定到一些常见的功能onClickonOpenonClose,你可以先定义一个函数,然后将其连接到两个.这是使JavaScript变得很棒的众多事情之一 - 作为可以轻松传递的一流对象的函数的可用性.

function handleClick(item) {
    /* do stuff here.
    Inside this function you can assume 'this' is the tree,
    since connect will ensure it runs in-context.
    */
}
var mytree = dijit.byId("mytree");
mytree.connect(mytree, "onClick", handleClick);
mytree.connect(mytree, "onOpen", handleClick);
mytree.connect(mytree, "onClose", handleClick);
Run Code Online (Sandbox Code Playgroud)

现在还有一个重要的问题是:我们应该在哪里做到这一点?最好的地方可能是传递给函数的内部dojo.ready(或dojo.addOnLoad同样的事情,ready在1.4中作为同义词添加),以便它只在以下情况下运行:

  • DOM由浏览器解析
  • 所有dojo.required模块都已加载
  • 如果您设置parseOnLoad: truedjConfig,在文档的HTML定义的所有部件都已经被实例化

所以,在你的dojo.requires 之后的某个时候,在脚本中,你会这样做:

dojo.ready(function() {
    /* code from previous example goes here */
});
Run Code Online (Sandbox Code Playgroud)

试一试.

另外,如果你对一些阅读感兴趣,我实际上已经写过我在这个编辑中提到的几个主题: