改变“这个”当使用 $.trigger() 在 jQuery 中触发自定义事件时

发布于 2024-12-05 10:52:47 字数 376 浏览 0 评论 0 原文

我正在尝试在 javascript 中实现事件池模式,类似于此处描述的内容: http://www.michaelhamrah .com/blog/2008/12/event-pooling-with-jquery-using-bind-and-trigger-managing-complex-javascript/

我需要能够设置上下文事件在被触发时关闭,而不是在绑定时关闭。是否有某种方法结合 $.trigger 和 $.proxy 来做到这一点?

I'm playing around with implementing an event pool pattern in my javascript, similar to what is described here: http://www.michaelhamrah.com/blog/2008/12/event-pooling-with-jquery-using-bind-and-trigger-managing-complex-javascript/

I need to be able to set the context of the event's closure(s) when they are triggered, rather than when they are bound. Is there some method of combining $.trigger and $.proxy to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

明媚如初 2024-12-12 10:52:47

我只是将其放在这里供其他人谷歌搜索,但这并不是触发时间部分整个绑定的实际答案。

这是一种解决方案,它包装绑定函数以根据触发时提供的参数设置其上下文。如果你想在触发时传递参数,那就不好了。

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;
})();

I'm just going to put this here for anyone else googling, but its not the actual answer to the whole binding at trigger time part.

This is a workaround solution that wraps the binding function to set its context according to an argument supplied at trigger time. It's no good if you want to pass args at trigger time though.

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;
})();
七月上 2024-12-12 10:52:47

首先:感谢您对自己问题的回答。它让我找到了自己的解决方案,我想我会与您和所有其他正在寻找它的人分享。

它是对您的修改,但仍然允许向您的 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 的自定义属性,以用作真实处理程序的实际上下文。如果未设置/计算结果为 false,则回退到旧的 this 上下文。

最终,我们使用传递给 jQuery().trigger 的所有参数手动调用实际处理程序。

如需使用,请检查链接的小提琴。

First off: Thank you for your answer to your own question. It brought me to my own solution which I thought I'd share with you and every other person searching for it.

It is a modification of yours that still permits passing additional arguments to your EventPool.Publish method. Note that my case looks a lot different from yours. Also note that jQuery.proxy does almost the same as Function.bind. (Btw, I do realize that this answer is already 2 years old.)

The demonstration code can be found here.

Snippets and explanations

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 essentially does the same as jQuery.proxy. We'll use this to memorize which handler to call in the end.


The router function calls the actual event handler, changing its context.

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 allows easily creating events using jQuery.Event (function). We're retrieving a custom property called context here to use as the actual context of the real handler. Fallback to the old this context if unset / evaluates to false.

Ultimately we're manually calling the actual handler with all arguments that were passed to jQuery().trigger.

For usage, check the linked fiddle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文