$ (this) innerhalb des AJAX-Erfolgs funktioniert nicht

103

Ich versuche, einen alten Code, der onclick verwendet, so zu ändern, dass ich das $ (this) verwende. Das Problem ist, dass $ (this) im Erfolg nicht funktioniert. Gibt es sowieso, um dies zu tun, ohne es als var festzulegen.

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

            }   
        }
    });

});
John Magnolia
quelle

Antworten:

231

Problem

thisBezieht sich innerhalb des Rückrufs auf das jqXHRObjekt des Ajax-Aufrufs und nicht auf das Element, an das der Ereignishandler gebunden war. Erfahren Sie mehr darüber, wie thisJavaScript funktioniert .


Lösungen

Wenn ES2015 + zur Verfügung steht, dann eine mit Pfeil Funktion wäre wahrscheinlich die einfachste Möglichkeit sein:

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

Sie können die contextOption einstellen :

Dieses Objekt wird zum Kontext aller Ajax-bezogenen Rückrufe. Standardmäßig ist der Kontext ein Objekt, das die im Aufruf verwendeten Ajax-Einstellungen darstellt ( $.ajaxSettingszusammengeführt mit den an übergebenen Einstellungen $.ajax). (...)

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

oder verwenden $.proxy:

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

oder behalten Sie einen Verweis auf den Wert thisaußerhalb des Rückrufs:

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

verbunden

Felix Kling
quelle
1
Da ich mit JavaScript besser werde und immer größere komplexe Projekte baue, hatte ich dies endlich etwas herausgefunden, aber diese Antwort zu sehen hilft mir sehr zu wissen, dass meine Annahmen korrekt sind und nicht nur theoretisch, also danke ich Ihnen persönlich wenn gegen SO Kommentarpolitik! =)
JasonDavis
Ich stimme zu (und danke), alle drei Optionen funktionieren. Ich wusste nichts über die Ajax-Kontextoption. Ein kleiner Nachteil ist, dass meine IDE (Phpstorm) die Option nicht erkennt, um das Bereichsproblem zu beheben, das bei JS-Abschlüssen wie diesem hilfreich erkannt wird. Durch das Hinzufügen des Proxy-Wrappers wird die Warnung nicht mehr angezeigt. Kontext: Dies muss ein unbekannter Trick in der vermutlich riesigen heuristischen Liste sein.
Scipilot
Das Gleiche gilt für die Kontextoption. Hat perfekt funktioniert.
Anna_MediaGirl
Exzellentes Beispiel!
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) {
                } 


});
Vishal Sanwar
quelle