Contrôler la valeur de ‘this’ dans un événement jQuery

J’ai créé un ‘contrôle’ à l’aide de jQuery et utilisé jQuery.extend pour l’aider à devenir aussi OO.

Lors de l’initialisation de mon contrôle, je connecte différents événements de clics

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

Notez que je passe ‘this’ comme argument de données dans la méthode bind. Je le fais pour pouvoir accéder aux données attachées à l’instance de contrôle plutôt qu’à l’élément qui déclenche l’événement click.

Cela fonctionne parfaitement, mais je soupçonne qu’il y a une meilleure façon

Ayant utilisé Prototype dans le passé, je me souviens d’une syntaxe de liaison qui vous permettait de contrôler la valeur de ‘this’ dans l’événement.

Quelle est la voie jQuery?

Vous pouvez utiliser jQuery.proxy() avec une fonction anonyme, un peu gênant que le «contexte» soit le deuxième paramètre.

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

J’aime bien votre façon d’utiliser une construction similaire:

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

et la première ligne de this.onClick:

 var self = event.data.self; 

J’aime cette manière car alors vous obtenez à la fois l’élément cliqué (comme ceci) et l’object “this” comme étant sans avoir à utiliser des fermetures.

jQuery a la méthode jQuery.proxy (disponible depuis 1.4).

Exemple:

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

Je ne pense pas que jQuery possède une fonctionnalité intégrée pour cela. Mais vous pouvez utiliser une construction d’aide comme celle-ci:

 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 cette manière, vous pouvez créer des «fonctions d’encapsulation» dynamics avec createDelegate () qui appelle la méthode avec un object donné comme scope «this».

Exemple:

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

vous pouvez utiliser la méthode de javascript comme ceci:

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

Les navigateurs compatibles HTML 5 fournissent une méthode de liaison sur Function.prototype qui est probablement la syntaxe la plus propre et qui ne dépend pas de la structure, bien qu’elle ne soit pas intégrée à IE avant IE 9. )

Basé sur votre exemple, vous pouvez l’utiliser comme ceci:

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

(remarque: le premier bind de cette instruction fait partie de jQuery et n’a rien à voir avec Function.prototype.bind )

Ou utiliser jQuery légèrement plus concis et à jour (et éliminer la confusion de deux types de bind différents):

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

jQuery ne prend pas en charge les liaisons et la méthode préférée consiste à utiliser des fonctions.

Parce qu’en Javascript, this.availableCategoryClick ne signifie pas appeler la fonction availableCategoryClick sur cet object, jQuery conseille d’utiliser cette syntaxe préférée:

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

Les concepts OO en Javascript sont difficiles à comprendre, la functional programming est souvent plus facile et plus lisible.

Voyant que les fonctions changent de scope, la manière la plus courante est de le faire à la main, avec quelque chose comme var self = this .

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