JavaScript触发多个事件但处理一次

时间:2014-08-22 19:43:47

标签: javascript jquery events event-handling eventtrigger

我不知道我是不是第一个遇到这个问题并且不想继续前进的人,但在我看来,它应该是其他人经历过的。另外,不要介意代码,因为我正在为此示例编写代码。实际应用与想法类似。

假设您有以下控制特定模型的对象:

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

我确实理解由于订阅工作方式的技术限制。实现必须确定谁订阅了所有这些事件,加入结果并发布事件。更重要的是,event.type不是为了表示单个事件名称而设计的。

但我确信有这些要求的用例。就我而言,它是一个动态指标小部件仪表板。有一种表示各种指标的指标结构。不同的指标会在不同的时间间不同的小部件依赖于多个指标。当从服务器获取度量标准时,我想为每个度量标准更改触发一个事件。小部件将刷新其数据。但是,我不希望依赖多个指标的小部件多次刷新。相反,我希望在通知哪个小部件的指标发生了变化后触发处理程序(这会过滤掉与小部件无关的指标进入处理程序)。

我意识到我可以制作metrics.update事件并传递一系列已更改的指标。在处理程序中,我可以弄清楚这是否与小部件有关。但理想情况下,我想避免这一步。

一个想法是定义一个jquery插件来缓冲将使用预定义“魔术”协议的事件:

model.bulkTriggerHandler( 'namechange agechange' );

插件bulkTriggerHandler可以解析事件字符串并考虑事件范围,然后它可以迭代内部对象并找出他们使用的订阅事件(非常hackish)$._data( object, "events" )方法,聚合为每个对象各自的相关事件列表,并触发某个事件处理程序。这个批量事件处理程序必须通过model.on( 'bulkUpdate' )进行分配......但这一切都非常糟糕。

无论如何,我很感激任何评论,甚至那些说我应该坚持使用metrics.update并且不打扰上述内容的评论;)

2 个答案:

答案 0 :(得分:0)

你不应该绕过触发,你应该环绕事件绑定。提供您自己的函数来绑定多个事件。它将为各个事件绑定自己的处理程序。此函数将跟踪已发生的事件,并且当列表中的所有事件发生时,它将调用提供的处理函数。调用者将其称为:

model.multiBind('namechange agechange', function() {
    ...
});

答案 1 :(得分:0)

我知道这篇文章有点陈旧但也许我仍然可以帮助...

//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);