108 votes

$(this) à l'intérieur d'un succès AJAX ne fonctionne pas

J'essaie de modifier un ancien code qui utilise onclick afin de pouvoir utiliser $(this). Le problème est que $(this) ne fonctionne pas à l'intérieur du succès. Existe-t-il un moyen de le faire sans le définir comme une variable ?

$('.addToCart').click(function() {

    $.ajax({
        url: 'cart/update',
        type: 'post',
        data: 'product_id=' + $(this).attr("data-id"),
        dataType: 'json',
        success: function(json) {

            if (json['success']) {

            $(this).addClass("test");

            }   
        }
    });

});

242voto

Felix Kling Points 247451

Problème

A l'intérieur du callback, this fait référence à la jqXHR de l'appel Ajax, et non l'élément auquel le gestionnaire d'événements était lié. En savoir plus sur la façon dont this fonctionne en JavaScript .


Solutions

Si vous disposez de l'ES2015+, l'utilisation d'une version de l'ES2015+ est possible. fonction de flèche serait probablement l'option la plus simple :

$.ajax({
    //...
    success: (json) => {
         // `this` refers to whatever `this` refers to outside the function
    }
});

Vous pouvez régler le context option :

Cet objet deviendra le contexte de tous les callbacks liés à Ajax. Par défaut, le contexte est un objet qui représente les paramètres Ajax utilisés dans l'appel ( $.ajaxSettings fusionné avec les paramètres passés à $.ajax ). (...)

$.ajax({
    //...
    context: this,
    success: function(json) {
         // `this` refers to the value of `context`
    }
});

ou utiliser $.proxy :

$.ajax({
    //...
    success: $.proxy(function(json) {
         // `this` refers to the second argument of `$.proxy`
    }, this)
});

ou conserver une référence à la valeur de this en dehors du rappel :

var element = this;

$.ajax({
    //...
    success: function(json) {
         // `this` refers to the jQXHR object
         // use `element` to refer to the DOM element
         // or `$(element)` to refer to the jQuery object
    }
});

Related

1 votes

Au fur et à mesure que je m'améliore avec JavaScript et que je construis des projets de plus en plus complexes, j'avais finalement compris cela, mais voir cette réponse m'aide beaucoup à savoir que mes hypothèses sont correctes et qu'il ne s'agit pas seulement de théorie, donc je vous remercie personnellement, même si cela va à l'encontre de la politique de commentaires du SO ! =)

0 votes

Je suis d'accord (et je remercie), ces trois options fonctionnent. Je ne connaissais pas l'option de contexte ajax. Un inconvénient mineur est que mon IDE (Phpstorm) ne reconnaît pas que l'option résout le problème de portée qu'il détecte utilement dans les fermetures JS comme celle-ci. L'ajout du proxy wrapper fait disparaître l'avertissement, donc context:this doit être une astuce inconnue dans sa liste heuristique probablement gigantesque.

0 votes

Idem pour l'option de contexte. Cela a parfaitement fonctionné.

-6voto

Vishal Sanwar Points 11
jQuery(".custom-filter-options .sbHolder ul li a").each(function () {
    var myStr = jQuery(this).text();
    var myArr = myStr.split(" (");
     url = 'your url'; // New Code
            data = myArr[0];
                try {
                    jQuery.ajax({
                        url : url,
                        context: this,
                        type : 'post',
                        data : data,
                        success : function(data) {
            if(data){
                  jQuery(this).html(data);
            }else{
                  jQuery(this).html(myArr[0]);
            }
                        }
                    });
                } catch (e) {
                } 

});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X