有人可以向我解释 Dojo 的“dojo/on”模块中究竟发生了什么吗?

Could somebody explain to me what exactly is happening in the Dojo's ''dojo/on" module?

我开始摆弄 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);
            }

        });
    }
);

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

在您的例子中,this 指向 image,属性 counter 指向 undefined。为此,您可以使用 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 将 return 一个范围改变的新函数,所以当你使用 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 一般情况。