5

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

次の例では、observer2 にはカスタム イベントがバインドされていないため、observer1 でのみ anotherCustomEvent が発生します。

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 Publish/Subscribe パターンについては、その章の少し下の方で言及しています。それは私の方法かもしれませんが、例の背後にあるコードがありません。

4

3 に答える 3

17

あなたのコメントから:

オブザーバーが登録できるリストを持つサブジェクトの代わりに、セレクターによってトリガーする要素をサブジェクトに指示する必要がある場合、これがどのように達成されるかわかりません

間違っている場合は訂正してください。ただし、パターンが 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 の 1 つによってトリガーされると、オブザーバー/サブスクライバーに通知され、メッセージがコンソールに記録されます。

この例ではdocument、理由のためにオブザーバーとして使用しています。イベントは DOM ツリーをバブルアップし、それをトリガーした要素の祖先である要素によってのみキャッチできます。documentは DOM ツリーのルートであるため、すべてのイベントを表示できます。#div1オブザーバーの場合、それ#div1自体によってトリガーされたイベントのみが表示されますが、 によってトリガーされたイベントは表示されません#div2

多分その制限があなたを混乱させたのですか?


#div1その制限を回避する方法はありますが、通常、によってトリガーされたイベントに基づいて何かをしたい場合は、要素#div2に設定したコールバックdocument(または両方の div に最も近い共通の祖先) から実行するだけです。とにかく、本当に別の方法が必要なようですので、ここに jQuery プラグインの形式の 1 つを示します。

$.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

于 2012-09-26T13:29:14.370 に答える
0

探しているものではないかもしれませんが、オブザーバーはリッスン イベントをサブスクライブできます。

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

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

        //remove observer
        $('ul li#Observer').removeClass('iObserver');
于 2012-09-25T22:02:12.533 に答える