Controlando el valor de ‘esto’ en un evento jQuery

Creé un “control” usando jQuery y utilicé jQuery.extend para ayudar a que sea lo más OO posible.

Durante la inicialización de mi control, conecto varios eventos de clic, como

jQuery('#available input', this.controlDiv).bind('click', this, this.availableCategoryClick); 

Tenga en cuenta que estoy pagando ‘esto’ como el argumento de datos en el método de enlace. Lo hago para poder acceder a los datos adjuntos a la instancia de control en lugar del elemento que activa el evento de clic.

Esto funciona perfectamente, sin embargo, sospecho que hay una mejor manera

Al haber usado Prototype en el pasado, recuerdo una syntax de enlace que le permitía controlar el valor de ‘this’ en el evento.

¿Cuál es la manera jQuery?

Puede usar jQuery.proxy() con función anónima, un poco incómodo que ‘context’ es el segundo parámetro.

  $("#button").click($.proxy(function () { //use original 'this' },this)); 

Me gusta tu camino, de hecho, uso una construcción similar:

 $('#available_input').bind('click', {self:this}, this.onClick); 

y la primera línea de this.onClick:

 var self = event.data.self; 

Me gusta de esta manera porque luego se obtiene el elemento presionado (como este) y el objeto “este” como uno mismo sin tener que usar cierres.

jQuery tiene el método jQuery.proxy (disponible desde 1.4).

Ejemplo:

 var Foo = { name: "foo", test: function() { alert(this.name) } } $("#test").click($.proxy(Foo.test, Foo)) // "foo" alerted 

No creo que jQuery tenga una función incorporada para eso. Pero podrías usar una construcción auxiliar como la siguiente:

 Function.prototype.createDelegate = function(scope) { var fn = this; return function() { // Forward to the original function using 'scope' as 'this'. return fn.apply(scope, arguments); } } // Then: $(...).bind(..., obj.method.createDelegate(obj)); 

De esta forma, puede crear funciones de contenedor dinámicas con createDelegate () que llaman al método con un objeto dado como su scope ‘this’.

Ejemplo:

 function foo() { alert(this); } var myfoo = foo.createDelegate("foobar"); myfoo(); // calls foo() with this = "foobar" 

puedes usar el método javascript bind así:

 var coolFunction = function(){ // here whatever involving this alert(this.coolValue); } var object = {coolValue: "bla"}; $("#bla").bind('click', coolFunction.bind(object)); 

Los navegadores compatibles con HTML 5 proporcionan un método de Function.prototype en Function.prototype que es, probablemente, la syntax más limpia y no depende del framework, aunque no está integrado en IE hasta IE 9. (Sin embargo, hay un polyfill para navegadores sin él). )

Según su ejemplo, puede usarlo así:

 jQuery('#available input', this.controlDiv).bind('click', this.availableCategoryClick.bind(this)); 

(nota al margen: el primer bind en esta statement es parte de jQuery y no tiene nada que ver con Function.prototype.bind )

O para usar jQuery un poco más conciso y actualizado (y eliminar la confusión de dos tipos diferentes de bind s):

 $('#available input', this.controlDiv).click(this.availableCategoryClick.bind(this)); 

jQuery no admite enlaces y la forma preferida es usar funciones.

Como en Javascript, this.availableCategoryClick no significa llamar a la función availableCategoryClick en este objeto, jQuery aconseja usar esta syntax preferida:

 var self = this; jQuery('#available input', self.controlDiv).bind('click', function(event) { self.availableCategoryClick(event); }); 

Los conceptos OO en Javascript son difíciles de entender, la progtwigción funcional a menudo es más fácil y legible.

Al ver que las funciones cambian el scope, la forma más común es hacerlo a mano, con algo como var self = this .

 var self = this $('.some_selector').each(function(){ // refer to 'self' here }