$ (questo) all'interno del successo di AJAX non funziona


103

Sto provando a cambiare un vecchio codice che usa onclick in modo da usare $ (this). Il problema è che $ (this) non funziona quando è all'interno del successo. Esiste comunque per farlo senza impostarlo come var.

$('.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");

            }   
        }
    });

});

Risposte:


231

Problema

All'interno del callback, thisfa riferimento jqXHRall'oggetto della chiamata Ajax, non all'elemento a cui era associato il gestore di eventi. Ulteriori informazioni su come thisfunziona in JavaScript .


soluzioni

Se ES2015 + è disponibile per te, l'utilizzo di una funzione freccia sarebbe probabilmente l'opzione più semplice:

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

Puoi impostare l' contextopzione :

Questo oggetto diventerà il contesto di tutti i callback relativi ad Ajax. Per impostazione predefinita, il contesto è un oggetto che rappresenta le impostazioni ajax utilizzate nella chiamata ( $.ajaxSettingsfuse con le impostazioni passate a $.ajax). (...)

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

oppure usa $.proxy:

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

oppure mantieni un riferimento al valore di thisoutside the callback:

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

Relazionato


1
Mentre sto migliorando con JavaScript e costruendo progetti complessi sempre più grandi, avevo finalmente in qualche modo capito questo, ma vedere questa risposta mi aiuta molto a sapere che le mie ipotesi sono corrette e non solo teoriche, quindi personalmente ti ringrazio, anche se contro la politica dei commenti SO! =)
JasonDavis

Sono d'accordo (e grazie), tutte e tre queste opzioni funzionano. Non sapevo dell'opzione contestuale ajax. Uno svantaggio minore è che il mio IDE (Phpstorm) non riconosce l'opzione risolve il problema di ambito che rileva in modo utile nelle chiusure JS come questa. L'aggiunta del proxy wrapper fa sparire l'avviso, quindi contesto: questo deve essere un trucco sconosciuto nella sua lista euristica presumibilmente gigantesca.
scipilot

Idem per l'opzione contestuale. Ha funzionato perfettamente.
Anna_MediaGirl

Ottimo esempio!
Jawwad Rizwan

-2
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) {
                } 


});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.