首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jquery观察者模式

Jquery观察者模式
EN

Stack Overflow用户
提问于 2012-09-26 03:52:17
回答 3查看 23.4K关注 0票数 5

我一直在互联网上寻找在jquery中实现观察者模式的例子。

我想要这样的。

代码语言:javascript
复制
observer1.observe(subject);
observer2.observe(subject);

为观察者定义一些自定义事件回调

代码语言:javascript
复制
observer1.bind('customEvent', function(contextData) {
  //Some code
});
observer1.bind('anotherCustomEvent', function(contextData) {
  //Some code  
});
observer2.bind('customEvent', function(contextData) {
  //Some code  
});

下面的代码行将触发两个观察者的customEvent回调

代码语言:javascript
复制
subject.trigger('customEvent', contextData);

而下面的代码将仅在observer1上触发anotherCustomEvent,因为observer2没有绑定该自定义事件

代码语言:javascript
复制
subject.trigger('anotherCustomEvent', contextData);

互联网上的指南更一般:

代码语言:javascript
复制
$( document ).on( "topicName" , function () {
  //..perform some behaviour
});

$( document ).trigger( "topicName" );

(来自http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjquery的示例)我不明白如何使用上面的代码来实现我正在寻找的东西。

要么我必须像这样(如果我像上面的例子一样保持它):

代码语言:javascript
复制
$(document).on("customEvent", function () {
  observer1.trigger("customEvent");
  observer2.trigger("customEvent");
});

$(subject).click(function() { 
  $(document).trigger("customEvent");
});

或者更好一点:

代码语言:javascript
复制
$(subject).click(function() { 
  observer1.trigger("customEvent");
  observer2.trigger("customEvent");
});

无论哪种方式,我都不得不编辑主题-click-callback或document-customEvent-callback,而不是告诉观察者订阅主题。

我是否误解了观察者模式,或者有什么方法可以实现我想要的吗?

http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript在本章后面提到了发布/订阅模式。对我来说,这可能是一种方法,但我遗漏了示例背后的代码。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-26 21:29:14

从你的评论中:

我不明白这是怎么实现的,因为你必须告诉主题哪些元素要由选择器触发,而不是让主题有一个观察者可以注册到的列表

如果我错了,请纠正我,但您似乎误解了该模式是如何在jQuery中实现的。你不会“告诉主题要触发哪些元素”,主题也没有“观察者可以注册的列表”。它是这样工作的:

  • 主体/发布者发出/触发某些事件(在您定义的某些情况下)。
  • 观察者/订阅者侦听某些事件。它保留了它订阅的事件的列表。
  • 这都是基于DOM事件的,所以它受到DOM事件模型的限制。

例如,考虑以下HTML:

代码语言:javascript
复制
<div id="div1">div 1</div>
<div id="div2">div 2</div>

让我们让内部div触发一个名为'custom'的自定义事件。你定义了什么时候应该发生,在这个例子中,当它们被点击时就会发生:

代码语言:javascript
复制
$('div').on('click', function(e) {
    $(this).trigger('custom');
});

现在让我们让document元素订阅那个自定义事件:

代码语言:javascript
复制
$(document).on('custom', function(e) {
    console.log('document is handling custom event triggered by ' + e.target.id);
});

当某个div触发自定义事件时,会通知观察者/订阅者,并将一条消息记录到控制台。

该示例使用document作为观察者的原因是:事件在DOM树上冒泡,并且只能由触发它的元素的祖先元素捕获。因为document是DOM树的根,所以它可以看到所有事件。如果#div1是我们的观察者,它将只看到由#div1本身触发的事件,而不会看到由#div2触发的事件。

也许这个限制就是让你困惑的地方?

有一些方法可以绕过这一限制,但通常情况下,如果您想根据#div2触发的事件对#div1执行某些操作,则只需在document元素(或两个div的最接近的共同祖先)上设置的回调中执行即可。无论如何,看起来你真的想要一个替代方案,所以这里有一个jQuery插件的形式:

代码语言:javascript
复制
$.fn.observe = function(eventName, callback) {
    return this.each(function(){
        var el = this;
        $(document).on(eventName, function(){
            callback.apply(el, arguments);
        })
    });
}

你可以这样使用它:

代码语言:javascript
复制
$('#div1').observe('custom', function(e) {
    // do something
});

现场示例:http://jsfiddle.net/JwJsP/1

票数 17
EN

Stack Overflow用户

发布于 2012-09-26 06:02:13

可能不是你想要的,但是观察者可以订阅监听事件:

代码语言:javascript
复制
        $(document).on('customEvent', '.iObserver', function() {
            console.log('i am observer');
        });

        // add observer
        $('ul li#Observer').addClass('iObserver');

        //remove observer
        $('ul li#Observer').removeClass('iObserver');
票数 0
EN

Stack Overflow用户

发布于 2015-02-18 23:09:39

如果您仍在寻找使用jQuery的事件引擎的实现,您可以尝试以下代码:

代码语言:javascript
复制
//The implementation   
(function($) {

    var o = $({});

    $.each({
        trigger: 'publish',
        on: 'subscribe',
        off: 'unsubscribe'
    }, function(key, val) {
        jQuery[val] = function() {
            o[key].apply(o, arguments);
        };
    });

})(jQuery);


// The way to use it is this:
var somedata = [1, 2, 3, 5, 4, 7, 8];
$.publish('myEvent', somedata); // with data
$.publish('myEvent'); // without data

$.subscribe('myEvent', function(event, data) {
    // handle the event
});
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12590091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档