使用 google 关闭创建事件
我想使用事件在谷歌闭包(GC)环境中的对象之间进行通信。
假设我有两个类 foobar.Boss
和 foobar.Employee
。老板想知道员工什么时候煮了咖啡,以及咖啡是否不含咖啡因(他本周将不再喝咖啡因)。
GC 已经提供了一些类,它们似乎提供了执行此操作的方法:goog.events.Event
和 goog.events.EventTarget
。
如果不知道更多,我认为它会像这样工作:
foobar.Employee.prototype.makeCoffee = function(isDecaf)
{
this.coffeeMaker.putCoffeeInMachine(isDecaf);
this.coffeeMaker.start();
var event = new goog.event.Event('COFFEE_ON', { isDecaf: isDecaf });
goog.events.dispatchEvent(event);
}
foobar.Boss.prototype.addEmployee = function(employee)
{
...
goog.events.listen(employee, 'COFFEE_ON', function(e)
{
if (e.target.isDecaf)
{
this.refillMug();
}
}, false, this);
...
}
这是正确的模式吗?我对 goog.events.EventTarget 类感到困惑——目标如何调度事件?难道目标没有发生什么事情吗?
这个问题很有帮助,但答案更直接将不胜感激。
I would like to use events to communicate between my objects in a google closure (GC) environment.
Suppose I have two classes foobar.Boss
and foobar.Employee
. The Boss wants to know when the Employee has made coffee, and whether or not that coffee is decaf (he's laying off the caffeine this week).
GC has made classes available that seem to provide the means to do this, goog.events.Event
and goog.events.EventTarget
.
Without knowing better, I'd think it would work like this:
foobar.Employee.prototype.makeCoffee = function(isDecaf)
{
this.coffeeMaker.putCoffeeInMachine(isDecaf);
this.coffeeMaker.start();
var event = new goog.event.Event('COFFEE_ON', { isDecaf: isDecaf });
goog.events.dispatchEvent(event);
}
foobar.Boss.prototype.addEmployee = function(employee)
{
...
goog.events.listen(employee, 'COFFEE_ON', function(e)
{
if (e.target.isDecaf)
{
this.refillMug();
}
}, false, this);
...
}
Is this a correct pattern? I am confused by the class goog.events.EventTarget
-- how does a target dispatch events? Doesn't a target have things happen to it?
This question is helpful, but a more direct answer would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
经过一段时间的研究,我现在的理解是,EventTarget 实际上扮演着双重角色,既是调度事件的实体,也是被监听的实体。因此,一种选择是让
Employee
继承goog.events.EventTarget
但我走了一条不同的路线。首先,我创建了一个新的事件类型,让老板知道咖啡是否不含咖啡因。
接下来,我创建了一个事件侦听器类型来调度这些事件。
我将这种类型的对象添加到我的
Employee
中。当员工重新倒咖啡时:
博斯曼先生会倾听。
请注意,这不会告诉我哪个员工重新倒了咖啡,因为事件目标将是
CoffeeEventTarget
的实例。如果您想要其中的所有Employee
,我想您可以将其添加为成员字段。如果您同意从goog.events.EventTarget
继承Employee
,那么您可以免费获得Employee
作为目标。Having looked at this for a while, my understanding is now that the
EventTarget
in fact plays a dual roll of being the entity that dispatches events and the entity that is listened to. So one option would be to haveEmployee
inheritgoog.events.EventTarget
but I have gone a different route.First I created a new event type that would let the Boss know if the coffee was decaf.
Next I created an event listener type to dispatch these events.
I added an object of this type to my
Employee
.When the employee refills the coffee:
Mr. Bossman listens for this.
Note that this won't tell me which employee refilled the coffee, because the event target will an instance of
CoffeeEventTarget
. If you wanted all ofEmployee
in there I suppose you could add it as a member field. If you were OK with inheriting toEmployee
fromgoog.events.EventTarget
then you getEmployee
for free as the target.我对 EventTarget 的看法是这样的:
按钮是一个目标,您可以注册该目标,以便在发生点击事件时收到有关其点击事件的通知。因此,单击的“目标”是按钮(您瞄准按钮,然后单击它)。但是,当按钮被单击时,并不是鼠标告诉每个人该按钮已被单击 - 按钮本身会发送该消息。
触及@ben-flynn提出的关于为什么有人需要/想要子类化EventTarget的问题:
如果你想监听按键按下事件,你可能会关心关于按下了什么键。您知道按下了什么键的方法是查找由 KeyDownEventTarget 调度的事件对象上的 keyCode 字段。另一方面,ButtonEventTarget 调度不同的事件对象,即 ClickEvent,其中没有 keyCode 字段。总而言之,您将 EventTarget 子类化的原因是,无论谁正在侦听将由该目标分派的事件,都知道触发事件时将分派哪个事件对象。
The way I think of EventTarget is this:
A button is a target, which you can register to be notified about its click event whenever one takes place. Thus, the "target" of a click is the button (you aim at the button, then click on it). But when the button gets clicked, it's not the mouse that tells everyone that the button was clicked - the button itself dispatches that message.
To touch on the question brought up by @ben-flynn about why would someone need/want to subclass EventTarget:
If you want to listen for key down events, you probably care about what key was pressed. The way you'd know what key was pressed is by looking up the keyCode field on the event object that is dispatched by the KeyDownEventTarget. On the other hand, a ButtonEventTarget dispatches a different event object, namely a ClickEvent, which does not have a keyCode field in it. So to summarize, the reason you'd subclass EventTarget is so whoever is listening for events that will be dispatched by that target know what event object will be dispatched when the event is triggered.
我会这样做...
让我们设置一个咖啡类型。如果我们要更进一步,我们可以有一个基本的 Coffee 类,然后用 DecafCoffee 类对其进行子类化。但让事情变得简单。
foobar.Coffee.js
我们的 Employee 类必须实现 goog.events.EventTarget 才能分派事件。您一定不要忘记使用
goog.base
或goog.events.EventTarget.call
调用父构造函数,因为这将设置类所需的内部变量。foobar.Employee.js
boss 类不需要做任何特殊的事情,因为它不会调度事件。它只需要一个我们可以调用的
#drinkCoffee()
方法。foobar.Boss.js
这是您将运行的主要 JavaScript 代码,您可以将其放置在任何您喜欢的位置,例如内联在浏览器中或其自己的脚本中。
main.js
Here's how I would do it...
Let's set up a coffee type. If we were to take this further we could have a base Coffee class and then sub class it with a DecafCoffee class. But lets keep things simple.
foobar.Coffee.js
Our Employee class must implement goog.events.EventTarget to be able to dispatch events. You mustn't forget to call the parent constructor with
goog.base
orgoog.events.EventTarget.call
either as this will setup internal variables the class needs.foobar.Employee.js
The boss class doesn't need to do anything special as it won't be dispatching events. It just needs a
#drinkCoffee()
method we can call.foobar.Boss.js
This is the main JavaScript code which you'll be running, you can put wherever you like, e.g. inline in the browser or in its own script.
main.js