简体   繁体   English

dojo如何覆盖dijit类方法

[英]dojo how to override dijit class method

I need to override onClick method in the Tree.js. 我需要覆盖Tree.js中的onClick方法。 Is there any common way to override dojo/dijit classes methods? 是否有任何常见的方法来覆盖dojo / dijit类方法?

I'm a bit confused, since you were already doing this in the last question you posted . 我有点困惑,因为你已经在你发布最后一个问题中这样做

You've got a few choices, depending on what you want to do. 你有几个选择,这取决于你想做什么。

Clobbering method stubs Clobbering方法存根

In the case of true stubs like onClick , it's potentially as easy as clobbering that method on your widget instance. 对于像onClick这样的真实存根,它可能就像在窗口小部件实例上破坏该方法一样容易。

Programmatically: 编程方式:

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

Or declaratively (this is exactly the same as what you were doing in your last question): 或者以声明的方式(这与您在上一个问题中所做的完全相同):

<div dojoType="dijit.Tree" ...>
    <script type="dojo/method" event="onClick" args="item,node,evt">
        /* handler code here */
    </script>
</div>

Connecting to method invocations 连接到方法调用

In other cases, perhaps you need to do something whenever a given method gets called, in which case you could use the widget's connect method (which is a nicer version of dojo.connect that will automatically clear itself when the widget is destroyed). 在其他情况下,也许您需要在调用给定方法时执行某些操作,在这种情况下,您可以使用窗口小部件的connect方法(这是一个更好的dojo.connect版本,它将在窗口小部件被销毁时自动清除)。 In that case you could do something like this: 在这种情况下,你可以做这样的事情:

Programmatically: 编程方式:

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

Declaratively, this can be done very similarly to the above, except instead of type="dojo/method" , make sure you use type="dojo/connect" 声明性地,这可以与上面非常相似,除了而不是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>

Note that when you connect like this, your code will execute after the method whose invocation you are connecting to. 请注意,当您像这样连接时,您的代码将您要连接的调用方法之后执行。 If you need to do something before , your best option is probably to dojo.declare your own extension to the widget. 如果您之前需要做某事,最好的选择可能是dojo.declare您自己的小部件扩展。 If you need to go that far, I'll elaborate, but I think you'll likely be set with one of the above options. 如果你需要走那么远,我会详细说明,但我认为你很可能会选择上述选项之一。

Edit #1: Connecting the dots (no pun intended...oh heck, yes it was) 编辑#1:连接点(没有双关语......哦,哎,是的)

Since it seems that my comment appended to my answer to the original question was somehow not clear enough, here's a code block modifying the original code in that question based on the simple two steps exactly as I explained in that comment. 因为似乎我的评论添加到我的答案,原来的问题在某种程度上还不够清楚,这里是一个代码块修改基于简单的两个步骤完全按照我在评论解释了这一问题的原代码。 The only tiny wrinkle is that the arguments passed to _onClick are slightly different. 唯一微小的皱纹是传递给_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>

This solution may feel a bit sub-optimal since it involves connecting to a method that's suggested to be private. 此解决方案可能感觉有点次优,因为它涉及连接到建议为私有的方法。 However, it's a way that should work regardless of whether openOnClick is true or not. 但是,无论openOnClick是否为true,它都应该有效。 If you are certain you're going to have openOnClick set to true , you could potentially write a single function, then connect it to both onClick and onOpen instead (both get passed the item, then the node). 如果您确定将openOnClick设置为true ,则可以编写单个函数,然后将其连接到onClickonOpen (两者都通过项目,然后是节点)。

Edit #2: Common functions, connecting programmatically 编辑#2:常用功能,以编程方式连接

To answer your follow-up questions, I'd like to actually address them in reverse order - since if you are interested in connecting programmatically, it will actually make the other question easier to answer. 为了回答你的后续问题,我想以相反的顺序解决它们 - 因为如果你有兴趣以编程方式连接,它实际上会使另一个问题更容易回答。

So first, to answer your connect question: you definitely don't want to be using dojo.byId , as that's not giving you the Tree widget, that's giving you some DOM node (probably the topmost) associated with the widget. 首先,回答你的connect问题:你绝对不想使用dojo.byId ,因为它没有给你Tree小部件,它给你一些与小部件相关的DOM节点(可能是最顶层的)。 As a general rule, dojo methods don't know anything about dijit stuff. 作为一般规则, dojo方法对dijit东西一无所知。

What you do want to be doing, is what I suggested above. 你想做什么,就是我上面提到的。 Here it is applied as per the code you attempted. 在这里,它是根据您尝试的代码应用的。 Also note that onClick has a capital C - another general rule: widget events use camel case notation, as a way to distinguish them from plain DOM events which don't. 另请注意, onClick有一个大写字母C - 另一个通用规则:小部件事件使用驼峰式表示法,作为区分它们的方法,而不是普通的DOM事件。

var mytree = dijit.byId("mytree");
mytree.connect(mytree, "onClick", function(item) {
    /* ... */
});

Now, to take that a step further and resolve your other inquiry, if you want to bind some common functionality to onClick and onOpen and onClose , you could define a function first, then connect it to both. 现在,为了更进一步并解决您的其他查询,如果您想将一些常用功能绑定到onClickonOpen以及onClose ,您可以先定义一个函数,然后将它连接到两者。 This is one of the many things that makes JavaScript awesome - the availability of functions as first-class objects that can be easily passed around. 这是使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);

Now there's one important remaining question: where should we do this? 现在还有一个重要的问题是:我们应该在哪里做到这一点? The best place is likely inside a function passed to dojo.ready (or dojo.addOnLoad , same thing, ready was added as a synonym in 1.4) so that it will run only after: 最好的地方可能是传递给dojo.ready的函数(或者dojo.addOnLoad ,同样的东西, ready已经作为1.4中的同义词添加),所以它只会在以下情况下运行:

  • The DOM is parsed by the browser DOM由浏览器解析
  • All dojo.require d modules have loaded 所有dojo.require d模块都已加载
  • If you set parseOnLoad: true in djConfig , all widgets defined in the document's HTML will already be instantiated 如果在djConfig设置parseOnLoad: true ,则文档HTML中定义的所有窗口小部件都将被实例化

So, sometime after your dojo.require s, in script, you'd do this: 所以,在你的dojo.require之后的某个时候,在脚本中,你会这样做:

dojo.ready(function() {
    /* code from previous example goes here */
});

Give it a shot. 试一试。

Also, if you're interested in a bit of reading, I've actually written about a couple of topics I touched on in this edit: 另外,如果你对一些阅读感兴趣,我实际上已经写过我在这个编辑中提到的几个主题:

You could use: 你可以使用:

dojo.connect(tree, 'onClick', function(item) {
    /** Your Action **/
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM