有人可以向我解释 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 一般情况。
我开始摆弄 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 一般情况。