使用谷歌关闭创建事件
Creating events with google closure
我想在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
弄糊涂了——目标如何调度事件?难道一个目标不会发生什么事吗?
这个问题很有帮助,但如果能给出更直接的答案,我们将不胜感激。
看了一段时间后,我的理解是,EventTarget
实际上扮演着分派事件的实体和被侦听的实体的双重角色。因此,一种选择是让Employee
继承goog.events.EventTarget
,但我走了另一条路。
首先,我创建了一个新的活动类型,让老板知道咖啡是否是无咖啡因的。
/**
* @constructor
* @extends {goog.events.Event}
*/
foobar.CoffeeEvent = function(isDecaf)
{
goog.events.Event.call(this, 'COFFEE_ON');
this.isDecaf = isDecaf;
};
goog.inherits(foobar.CoffeeEvent, goog.events.Event);
接下来,我创建了一个事件侦听器类型来调度这些事件。
/**
* @constructor
* @extends {goog.events.EventTarget}
*/
foobar.CoffeeEventTarget = function()
{
goog.events.EventTarget.call(this);
};
goog.inherits(foobar.CoffeeEventTarget, goog.events.EventTarget);
我在Employee
中添加了一个这种类型的对象。
foobar.Employee = function()
{
...
this.coffeeEvents = new foobar.CoffeeEventTarget();
...
}
员工补充咖啡时:
foobar.Employee.prototype.makeCoffee = function(isDecaf)
{
this.coffeeMaker.putCoffeeInMachine(isDecaf);
this.coffeeMaker.start();
var event = new foobar.CoffeeEvent(isDecaf);
this.coffeeEvents.dispatchEvent(event);
}
Mr。老板听了。
foobar.Boss.prototype.addEmployee = function(employee)
{
...
goog.events.listen(employee.coffeeEvents, 'COFFEE_ON', function(e)
{
if (e.isDecaf)
{
this.refillMug();
}
}, false, this);
...
}
请注意,这不会告诉我哪个员工重新装满了咖啡,因为事件目标将是CoffeeEventTarget
的实例。如果您希望所有Employee
都在其中,我想您可以将其添加为成员字段。如果您可以从goog.events.EventTarget
继承到Employee
,那么您可以免费获得Employee
作为目标。
我对EventTarget的看法是:
按钮是一个目标,您可以注册该按钮,以便在发生点击事件时收到通知。因此,点击的"目标"是按钮(你瞄准按钮,然后点击它)。但当按钮被点击时,并不是鼠标告诉每个人按钮被点击了,而是按钮本身发出消息。
为了触及@ben flynn提出的关于的问题,为什么有人需要/想要将EventTarget子类化:
如果您想监听按键按下事件,您可能会关心按下了什么键。您可以通过查找KeyDownEventTarget调度的事件对象上的keyCode字段来了解按下了什么键。另一方面,ButtonEventTarget调度一个不同的事件对象,即ClickEvent,该对象中没有keyCode字段。因此,总的来说,您之所以将EventTarget子类化,是因为无论谁在侦听将由该目标调度的事件,都知道当事件被触发时将调度什么事件对象。
以下是我的操作方法…
让我们设置一个咖啡类型。如果我们更进一步,我们可以有一个基础咖啡课程,然后用DecafCoffee课程进行细分。但让我们保持简单。
foobar.Coffee.js
/**
* @fileoverview Coffee class
*/
goog.provide('foobar.Coffee');
/**
* @constructor
*/
foobar.Coffee = function(){
//...
};
我们的Employee类必须实现goog.events.EventTarget才能调度事件。不要忘记用goog.base
或goog.events.EventTarget.call
调用父构造函数,因为这将设置类所需的内部变量。
foobar.Employe.js
/**
* @fileoverview Implements the Employee class
*/
goog.provide('foobar.Employee');
goog.require('goog.events.EventTarget');
goog.require('foobar.Coffee');
/**
* @constructor
*/
foobar.Employee = function(){
// Calls the parent class (goog.events.EventTarget)
goog.base(this);
};
goog.inherits(foobar.Employee, goog.events.EventTarget);
/**
* Make a coffee
*/
foobar.Employee.prototype.makeCoffee = function(){
// Determine what coffee type to make ...
// Create the coffee
var coffee = new foobar.Coffee();
this.dispatchEvent({
type: "decaf_coffee",
target: coffee
});
};
boss类不需要做任何特殊的事情,因为它不会调度事件。它只需要一个我们可以调用的#drinkCoffee()
方法。
foobar.Boss.js
/**
* @fileoverview Implements the Boss class
*/
goog.provide('foobar.Boss');
/**
* @constructor
*/
foobar.Boss = function(){
//...
};
/**
* Make this boss drink coffee
* @param {foobar.Coffee} coffee The coffee to drink
*/
foobar.Boss.prototype.drinkCoffee = function(coffee){
//....
};
这是你将要运行的主要JavaScript代码,你可以把它放在任何你喜欢的地方,例如在浏览器中内联或在它自己的脚本中。
main.js
goog.require('foobar.Boss');
goog.require('foobar.Employee');
goog.require('goog.events');
// Jane is the boss of Sam, but we will use lower case as I typically
// only capitalise the first letter to indicate a constructor.
var jane = new Boss();
var sam = new Employee();
// Set up event listening
goog.events.listen(sam, "decaf_coffee", function(e){
var coffee = e.target;
// We've got the decaf coffee Sam made, now Jane can enjoy drinking it
jane.drinkCoffee(coffee);
}, false, this);
// Tell Sam to make a coffee
sam.makeCoffee();
- 如何在jQuery Mobile 1.4 Datepicker中创建事件
- 如何在浏览器页面切换到我的网站选项卡时创建事件,如gmail中的聊天框状态更改
- 正在创建事件侦听器以从本地存储中删除对象
- 如何为范围滑块创建事件处理程序
- 在完整日历的Dayclick事件上触发jQuery qTip,然后使用其中的按钮创建事件
- 为什么我的 UI/可拖动“创建”事件被传递一个空的“ui”对象
- 在嵌套循环中创建事件处理程序的效率:我在这里创建了 1440 个函数
- JavaScript - 动态创建事件侦听器
- 使用 Javascript 关闭窗口时创建事件
- Outlook.com 应用程序 - 如何在预填充 HTML 正文的情况下创建事件
- 如何在 GAS 中转换和传递日期以在 Google 日历中创建事件
- 在某些数据之后创建事件对象
- 如何在javascript中动态创建事件和事件处理程序
- Office 365日历API基于创建事件触发对应用程序的调用
- 使用谷歌关闭创建事件
- 如何挂钩到express会话创建事件
- 删除并重新创建事件的元素:
- 如何在单独的页面上创建事件
- 为用户在Firefox或Chrome中右键单击并检查元素创建事件处理程序
- 如何在点击上一页/下一页时创建事件?FullCalendar