$ (this) di dalam AJAX sukses tidak bekerja

103

Saya mencoba mengubah beberapa kode lama yang menggunakan onclick sehingga saya menggunakan $ (this). Masalahnya adalah bahwa $ (this) tidak berfungsi ketika berada di dalam kesuksesan. Apakah ada cara untuk melakukan ini tanpa mengaturnya sebagai 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");

            }   
        }
    });

});
John Magnolia
sumber

Jawaban:

231

Masalah

Di dalam callback, thismengacu pada jqXHRobjek panggilan Ajax, bukan elemen yang terikat pada event handler. Pelajari lebih lanjut tentang cara thisbekerja di JavaScript .


Solusi

Jika ES2015 + tersedia untuk Anda, menggunakan fungsi panah mungkin merupakan opsi paling sederhana:

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

Anda dapat mengatur contextopsi :

Objek ini akan dijadikan konteks semua callback terkait Ajax. Secara default, konteks adalah objek yang mewakili pengaturan ajax yang digunakan dalam panggilan ( $.ajaxSettingsdigabungkan dengan pengaturan yang diteruskan ke $.ajax). (...)

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

atau gunakan $.proxy:

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

atau simpan referensi ke nilai di thisluar 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
    }
});

Terkait

Felix Kling
sumber
1
Ketika saya menjadi lebih baik dengan JavaScript dan membangun proyek kompleks yang lebih besar dan lebih besar, saya akhirnya agak memahami hal ini, tetapi melihat jawaban ini sangat membantu saya untuk mengetahui bahwa asumsi saya benar dan bukan hanya teori jadi saya pribadi berterima kasih, bahkan jika bertentangan dengan kebijakan komentar SO! =)
JasonDavis
Saya setuju (dan terima kasih), ketiga opsi ini berfungsi. Saya tidak tahu tentang opsi konteks ajax. Kelemahan kecil adalah bahwa IDE saya (Phpstorm) tidak mengenali opsi untuk menyelesaikan masalah lingkup yang dideteksi dengan sangat membantu dalam penutupan JS seperti ini. Menambahkan pembungkus proxy akan menghilangkan peringatan, jadi konteksnya: ini pasti trik yang tidak diketahui dalam daftar heuristik yang mungkin sangat besar.
scipilot
Ditto untuk opsi konteks. Bekerja dengan sempurna.
Anna_MediaGirl
Contoh Luar Biasa!
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
sumber