簡體   English   中英

Jquery觀察者模式

[英]Jquery Observer pattern

我一直在互聯網上查看在jquery中實現觀察者模式的例子。

我想這樣

observer1.observe(subject);
observer2.observe(subject);

為觀察者定義一些自定義事件回調

observer1.bind('customEvent', function(contextData) {
  //Some code
});
observer1.bind('anotherCustomEvent', function(contextData) {
  //Some code  
});
observer2.bind('customEvent', function(contextData) {
  //Some code  
});

然后,以下行將觸發兩個觀察者的customEvent回調

subject.trigger('customEvent', contextData);

而以下只會在observer1上觸發anotherCustomEvent,因為observer2沒有綁定的自定義事件

subject.trigger('anotherCustomEvent', contextData);

互聯網上的指南更為通用:

$( document ).on( "topicName" , function () {
  //..perform some behaviour
});

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

(來自http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjquery的例子)我看不出上面的代碼如何用來完成我正在尋找的東西。

要么我必須這樣做(如果我保持它像上面的例子):

$(document).on("customEvent", function () {
  observer1.trigger("customEvent");
  observer2.trigger("customEvent");
});

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

或者更好一點:

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

無論哪種方式,我都不得不編輯subject-click-callback或document-customEvent-callback,而不是告訴觀察者訂閱主題。

我是否誤解了觀察者模式或有沒有辦法實現我正在尋找的東西?

http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript在該章中提到了發布/訂閱模式。 這對我來說可能是一種方式,但我錯過了示例背后的代碼。

來自你的評論:

當你不得不告訴主題哪些元素由選擇器觸發而不是具有觀察者可以注冊到的列表的主題時,我只是看不出這是如何實現的。

如果我錯了,請糾正我,但你似乎誤解了jQuery中如何實現模式。 您沒有“告訴主題觸發哪些元素”,並且主題沒有“觀察者可以注冊的列表”。 它的工作原理如下:

  • 主題/發布者發出/觸發某些事件(在您定義的某些情況下)。
  • 觀察者/訂閱者監聽某些事件。 它保留了訂閱的事件列表。
  • 這都是基於DOM事件的,所以它受DOM事件模型的限制。

例如,請考慮以下HTML:

<div id="div1">div 1</div>
<div id="div2">div 2</div>

讓內部div觸發一個名為'custom'的自定義事件。 您可以定義何時應該發生這種情況,在此示例中,單擊它們時會發生這種情況:

$('div').on('click', function(e) {
    $(this).trigger('custom');
});

現在讓我們讓document元素訂閱該自定義事件:

$(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插件的形式:

$.fn.observe = function(eventName, callback) {
    return this.each(function(){
        var el = this;
        $(document).on(eventName, function(){
            callback.apply(el, arguments);
        })
    });
}

你可以像這樣使用它:

$('#div1').observe('custom', function(e) {
    // do something
});

實例: http//jsfiddle.net/JwJsP/1

可能不是你想要的,但觀察者可以訂閱聽取事件:

        $(document).on('customEvent', '.iObserver', function() {
            console.log('i am observer');
        });

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

        //remove observer
        $('ul li#Observer').removeClass('iObserver');

如果您仍在使用jQuery的事件引擎尋找一些實現,您可以嘗試以下代碼:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM