【发布时间】:2017-01-16 23:36:55
【问题描述】:
我不知道我是不是第一个遇到这个问题并且不想继续前进的人,但在我看来,其他人应该也经历过。另外,不要介意代码,因为我正在为这个示例编写代码。实际应用思路类似。
假设您有以下控制某个模型的对象:
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' )... 分配,但这一切都非常 hacky。
无论如何,我会很感激任何 cmets,即使是那些说我应该坚持使用 metrics.update 并且不理会上述内容的人 ;)
【问题讨论】:
-
你考虑过 jquery bind() 吗?
-
不,除非最近对 .bind 进行了修订,否则它的工作方式类似于 .on 方法。这里的问题不是绑定到事件,而是触发和处理它们。您不能使用 .trigger( 'eventA eventB' ) 而是立即处理它们。我刚刚发现一张票被提出并解决为 jquery 的“wontfix”:bugs.jquery.com/ticket/12734.
标签: javascript jquery events event-handling eventtrigger