我正在尝试在javascript中实现一个事件池模式,类似于这里所描述的:http://www.michaelhamrah.com/blog/2008/12/event-pooling-with-jquery-using-bind-and-trigger-managing-complex-javascript/
我需要能够在事件闭包被触发时设置上下文,而不是在它们被绑定时。是否有组合$的方法。触发器和$。代理做这件事?
我将把它放在这里,但它不是整个绑定在触发时间部分的实际答案。
这是一个变通的解决方案,它包装绑定函数,使其根据触发时提供的参数设置上下文。如果你想在触发时传递参数,那就不好了。
EventPool = (function() {
function EventPool() {}
EventPool.Subscribe = function(event, fn) {
return $(this).bind(event, $.proxy(function(event, context) {
context = context != null ? context : this;
return $.proxy(fn, context)(event);
}, this));
};
EventPool.Publish = function(event, context) {
return $(this).trigger(event, context);
};
return EventPool;
})();
首先:谢谢你对自己问题的回答。这让我找到了我自己的解决方案,我想我会与你和其他每一个寻找它的人分享。
这是你的修改,仍然允许传递额外的参数给你的EventPool.Publish
方法。请注意,我的情况与你的情况大不相同。也注意到jQuery.proxy
和Function.bind
几乎是一样的。(顺便说一句,我确实意识到这个答案已经是两年前的了。)
演示代码可以在这里找到。
片段和解释
function subscribe( ) {
var args = argsToArray(arguments), // Helper function to convert `arguments` object into array. Otherwise `Function.apply` won't accept it.
fn = args[args.length - 1], // The event handler is always the last argument passed to `jQuery.on`.
$this = $(this);
args[args.length - 1] = router.bind(this, fn); // Change handler to our context changer.
$this.on.apply($this, args); // Call jQuery().on() with modified arguments.
return this;
}
Function.bind
本质上与jQuery.proxy
相同。我们将使用它来记住最后调用哪个处理程序。
router
函数调用实际的事件处理程序,改变其上下文。
function router( ) {
var args = argsToArray(arguments),
fn = args.shift(), // Remember, we prefixed `router` with the actual event handler.
evt = args[0],
context = evt.context || this;
// No need to reference the context twice.
delete evt.context;
fn.apply(context, args);
}
jQuery允许使用jQuery.Event
(函数)轻松创建事件。我们在这里检索一个名为context
的自定义属性,将其用作实际处理程序的实际上下文。如果unset/求值为false,则返回到旧的this
上下文。
最终,我们用传递给jQuery().trigger
的所有参数手动调用实际的处理程序。
用法请查看链接的小提琴