有人可以向我解释 Dojo 的“dojo/on”模块中到底发生了啥吗?

Posted

技术标签:

【中文标题】有人可以向我解释 Dojo 的“dojo/on”模块中到底发生了啥吗?【英文标题】:Could somebody explain to me what exactly is happening in the Dojo's ''dojo/on" module?有人可以向我解释 Dojo 的“dojo/on”模块中到底发生了什么吗? 【发布时间】:2016-08-18 16:38:35 【问题描述】:

我开始摆弄 Dojo.js,遇到了一个我不明白的东西。

我正在尝试创建自己的小部件。该小部件将非常简单——它只会查询页面上的所有图像并让它们监听 'click' 事件。每次单击都会将小部件的 counter 属性增加 1。

这是我的看法:

define(
    [                   
        "dojo/_base/declare",
        "dojo/query",
        "dijit/_WidgetBase",
        "dijit/_TemplatedMixin",
        "dojo/text!myProject/folder/myWidgetTemplate.html",
    ],
    function(declare, query, _WidgetBase, _TemplatedMixin, template) 
        declare("MyWidget", [_WidgetBase, _TemplatedMixin], 

            templateString: template,
            counter: 0,

            onClick: function(evt) 
                this.counter++;
                console.log(this.counter);
            ,

            postCreate: function() 
                query("img").on("click", this.onClick);
            

        );
    
);

小部件初始化,我确实可以点击图像,但控制台总是返回 undefined。 似乎我缺少关于 dojo/on 模块如何工作的一些核心方面。有人可以向我解释一下我的代码到底发生了什么吗?

【问题讨论】:

注意:据我了解,您的小部件没有任何可见的 UI(因为图像位于页面中的任何位置)。在这种情况下,您可以删除_TemplatedMixin,从而删除您的myProject/folder/myWidgetTemplate.html 模板文件以及属性templateString: template, 你说得对,谢谢指出! (这个小部件实际上使用了它自己的 UI,我只是去掉了那部分代码以使问题更简单。但是,我忘了删除 _TemplatedMixin。但提醒一下以防万一总是好的,所以谢谢!)跨度> 【参考方案1】:

在您的情况下,this 指向image,属性counterundefined。为此,您可以使用dojo/base/lang 模块

define(
    [                   
        "dojo/_base/declare",
        "dojo/_base/lang", //add this
        "dojo/query",
        "dijit/_WidgetBase",
        "dijit/_TemplatedMixin",
        "dojo/text!myProject/folder/myWidgetTemplate.html",
    ],
    function(declare, lang, query, _WidgetBase, _TemplatedMixin, template) 
        declare("MyWidget", [_WidgetBase, _TemplatedMixin], 

            templateString: template,
            counter: 0,

            onClick: function(evt) 
                this.counter++;
                console.log(this.counter);
            ,

            postCreate: function() 
                //lang.hitch will return a new function with scope changed
                query("img").on("click", lang.hitch(this, this.onClick));
            

        );
    
);

lang.hitch 将返回一个改变范围的新函数,因此当您使用 this 时,它将指向您传递的目标

您可以通过在 html 中声明事件来避免使用lang,例如

<img src="myImage.jpg" data-dojo-attach-event="onClick: onClick"/>  

其中onClick: onClick 可以读作event: functionName,并且functionName 必须存在于您的小部件中。

注意,您可以使用 javascript 的原生 bind function 执行相同操作,只需执行

query("img").on("click", this.onClick.bind(this));

你可以查看这个答案access this on external callback 它不是关于dojo,而是关于一般的Javascript。

【讨论】:

附带说明,当 img 包含在小部件本身中时,我建议使用 dojo-attach-points 而不是查询(这里不是这种情况,但值得一提) 有趣!这是为什么呢? query() 需要额外的操作,而 attach-points 是在小部件被激活时免费创建的 请注意:如果浏览器目标兼容 ES5,我相信 lang.hitch 可以被本机 .b​​ind() 替换。 @Radex 我什至举了一个例子来说明如何使用bind,你阅读了整个答案吗?

以上是关于有人可以向我解释 Dojo 的“dojo/on”模块中到底发生了啥吗?的主要内容,如果未能解决你的问题,请参考以下文章

Events with Dojo(翻译)

Ace Editor 和 Dojo 1.9 与 AMD

DOJO官方API翻译或解读-dojo/_base/lang --hitch()

Dojo on (events) 在声明时触发

Dojo:如何设置禁用新按钮

arcgis自定义infowindow