2011-12-03 5 views
4

私はJavascriptを持つオブジェクトリテラル:Javascriptのリテラルオブジェクトはイベントを起動できますか?

var Toolbar = { 

    init: function(toolbar) { 
     this.Bar = $(toolbar); // scope is Toolbar object literal 

     this.Bar.find('clearButton').click(function() { 
      this.trigger('clear'); // doesn't work! 
      this.Bar.trigger('clear'); // works! 
    } 
} 

Toolbar.init($('div.toolbar')); 
Toolbar.bind('clear', function() { ... }); // doesn't work! 
Toolbar.Bar.bind('clear', function() { ... }); // works! 

私はむしろリテラルで参照ツールバーのDOMオブジェクトよりリテラルツールバーのオブジェクトにclearイベントをトリガすることができるようにしたいと思います。これは可能なのか、もしそうなら、私はどうしたらいいですか?

+0

「init」に何かを渡すべきではありませんか?とにかく、私は、エラーメッセージは "なぜそれが動作しない"についてかなり明確にすべきだと思います。最低でも、*それらを投稿に含める*。 –

+0

私の質問を訂正し、 'init()'呼び出しにjQueryオブジェクトを含めるのを忘れました。私が「うまくいきません」と言うと、オブジェクトリテラルはイベントを発生させるようには見えません(DOMオブジェクトではないので意味があります)。 –

答えて

1

これは動作するはずです:

var Toolbar = { 

    init: function(toolbar) { 
     this.Bar = $(toolbar); // scope is Toolbar object literal 

     this.Bar.find('.clearButton').click($.proxy(function() { 
      $(this).trigger('clear'); // should work now 
      this.Bar.trigger('clear'); // still works 
     }, this)); 
    } 
}; 

Toolbar.init($('div.toolbar')); 

$(Toolbar).bind('clear', function() { 
    console.log('Toolbar'); 
}); // should work now 

Toolbar.Bar.bind('clear', function() { 
    console.log('Toolbar.Bar'); 
}); // still works 
  1. あなたはクリック機能でthisの参照を維持する必要があります。私は$.proxyを使いました。一部の人々は、jQueryの機能にアクセスするために$()に包まれる必要がありますのでvar self = this;

  2. ToolbarはjQueryオブジェクトではありません使用します。また、クリック機能でToolbarインスタンスを参照するthisをラップします。

0

これはいかがですか? :

var Toolbar = { 

    init: function(toolbar) { 
     this.Bar = $(toolbar); // scope is Toolbar object literal 

     this.trigger = 
      function() { this.Bar.trigger.apply(this.Bar, arguments); }; 

     this.bind = function() { this.Bar.bind.apply(this.Bar, arguments); }; 

     this.Bar.find('clearButton').click(function() { 
      this.trigger('clear'); 
    } 
}; 

Toolbar.init(); 
Toolbar.bind('clear', function() { ... }); 

必要に応じて、折り返しを処理する機能を簡単に作成できます。あなたが好むように、これらのいずれかを、:

前者が後者は、前者はどんな this.Barのラッパーに thisを行いますということで差は、現在ある( wrapperitize(this, 'Bar', 'trigger', 'bind')として wrapperitize(this, this.Bar, 'trigger', 'bind')、後者として呼び出されます
function wrapperitize(wrapper, wrappee, method /*, more_methods...*/) 
{ 
    wrapper[method] = function() { wrappee[method].apply(wrappee, arguments); }; 
    for(var i = 3; i < arguments.length; ++i) 
     wrapperitize(wrapper, wrappee, arguments[i]); 
} 

function wrapperitize(wrapper, wrappeeProp, method /*, more_methods...*/) 
{ 
    wrapper[method] = function() 
    { 
     wrapper[wrappeeProp][method].apply(wrapper[wrappeeProp], arguments); 
    }; 
    for(var i = 3; i < arguments.length; ++i) 
     wrapperitize(wrapper, wrappeeProp, arguments[i]); 
} 

this.Barが今まで将来的になるかもしれません何のためのラッパーにthisを行います。

(注、方法によって、再帰のほんの少し。これは、閉鎖はJavaScriptで仕事のやり方に、問題の変数捕捉を避けるためです。 )

0

Toolbarオブジェクトのメソッドを呼び出せるようにするには、そこに定義する必要があります。あなたはこれらのメソッドの非常に多くを追加するには、この方法を必要としない場合は、あなただけのツールバーオブジェクト自体でそれらのそれぞれを定義することができます。しかし

var Toolbar = { 
    clear: function() { this.Bar.trigger('clear'); } 

    init: function(toolbar) { 
     this.Bar = $(toolbar); // scope is Toolbar object literal 
     this.Bar.find('clearButton').click(function() { 
      this.clear(); 
    } 
} 

あなたがそれらの非常に多くを呼び出すために必要がある場合、これはすぐになります醜い。 実際にツールバーオブジェクトのjqueryオブジェクトで使用できるすべてのメソッドを呼び出せたい場合は、for inループを使用してすべてをループし、それらをツールバーオブジェクトに追加することができます面倒で、読みづらい、非効率的で、バグが発生する可能性があります。私は$(toolbar)を使用して、そのオブジェクトのメソッドを呼び出すときはいつでも、それらの短所をすべて取り除くことができます。 :D

関連する問題