我不知道我是否是第一个遇到这个问题的人,不想继续前进,但在我看来,其他人应该已经经历过了。另外,不要介意代码,因为我正在为这个示例编写代码。实际的应用程序在思想上是相似的。
假设你有以下对象控制某个模型:
var model = $({
name: 'user',
age: 30,
sex: 'male'
});
model.on( 'namechange agechange sexchange', function ( event ) {
console.log( 'Model experienced a ' + event.type );
});
model.triggerHandler( 'namechange' );
上述代码的输出将是Model experienced a namechange
。
如果我想触发多个事件,代码看起来像:
model.triggerHandler( 'namechange' );
model.triggerHandler( 'agechange' );
model.triggerHandler( 'sexchange' );
输出将相应地重复。
但是我真正想要的是当触发器方法触发一个或多个事件时触发处理程序。
model.triggerHandler( 'namechange agechange' ); // hander is bound to both but called once
model.triggerHandler( 'agechange' ); // hander is bound to one and called once
model.triggerHandler( 'namechange carchange agechange' ); // hander is bound to two of the three but called once
由于订阅的工作方式,我确实理解技术上的限制。实现必须弄清楚谁订阅了所有这些事件,加入结果并发布事件。事件更是如此。类型不是为表示单个事件名称而设计的。
然而,我确信有这样的需求的用例。在我的例子中,它是一个动态指标小部件仪表板。有一个表示各种度量标准的度量结构。不同的度量标准以不同的时间间隔更新。不同的小部件依赖于多个指标。当从服务器获取一个(多个)指标时,我希望为每个指标更改触发一个事件。小部件将刷新它们的数据。但是,我不希望一个依赖于多个指标来刷新多次的小部件。相反,我希望处理程序在通知该小部件的哪个指标发生了变化时被触发(这会过滤掉与进入处理程序的小部件无关的指标)。
我意识到我可以创建一个metrics.update
事件并传递一个已更改的指标数组。在处理程序中,我可以弄清楚这是否与小部件有关。但理想情况下,我希望避免这一步。
一个想法是定义一个jquery插件来缓冲事件,使用预定义的"魔法"协议:
model.bulkTriggerHandler( 'namechange agechange' );
插件bulkTriggerHandler
可以解析事件字符串并考虑事件范围,然后它可以遍历内部对象并使用(非常hackish) $._data( object, "events" )
方法找出它们订阅的事件,为每个对象聚合各自的相关事件列表,并触发某个事件处理程序。此批量事件处理程序必须通过model.on( 'bulkUpdate' )
分配…但是这些都很粗俗。
无论如何,我很感谢任何评论,即使是那些说我应该坚持使用metrics.update
而不是上面的;)
您不应该围绕触发进行包装,而应该围绕事件绑定进行包装。提供自己的函数来绑定多个事件。它将为单个事件绑定自己的处理程序。该函数将跟踪发生了哪些事件,当列表中的所有事件发生时,它将调用提供的处理程序函数。调用者将调用它为:
model.multiBind('namechange agechange', function() {
...
});
我知道这篇文章有点陈腐,但也许我仍然可以帮助…
//Define a single function that takes an event object
function handleChange(event)
{
// Log a string parameterized with event.type
console.log( 'Model experienced a ' + event.type );
}
// Register handlers one at a time but reuse the function
model.on( 'namechange', handleChange);
model.on( 'agechange', handleChange);
model.on( 'sexchange', handleChange);
它将能够一次为N个事件定义处理程序有点酷,但这似乎是一种避免重复代码的方法。
你总是可以写一个实用函数,它接受一个数组或任意数量的位置参数,并为你重复执行.on
。我将被这样称呼:
handle(model, ["namechange", "agechange", "sexchange"], handleChange);