$ (นี้) ภายในความสำเร็จของ AJAX ไม่ทำงาน


103

ฉันกำลังพยายามเปลี่ยนรหัสเก่าที่ใช้ onclick เพื่อให้ฉันใช้ $ (this) ปัญหาคือ $ (this) ไม่ทำงานเมื่ออยู่ในความสำเร็จ จะมีการทำเช่นนี้โดยไม่ตั้งค่าเป็นตัวแปรหรือไม่

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

            }   
        }
    });

});

คำตอบ:


233

ปัญหา

ภายในการเรียกกลับthisหมายถึงjqXHRออบเจ็กต์ของการเรียก Ajax ไม่ใช่องค์ประกอบที่ตัวจัดการเหตุการณ์ถูกผูกไว้ เรียนรู้เพิ่มเติมเกี่ยวกับวิธีการthisทำงานใน JavaScript


แนวทางแก้ไข

หาก ES2015 + พร้อมใช้งานสำหรับคุณการใช้ฟังก์ชันลูกศรน่าจะเป็นตัวเลือกที่ง่ายที่สุด:

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

คุณสามารถตั้งค่าcontextตัวเลือก :

วัตถุนี้จะสร้างบริบทของการเรียกกลับที่เกี่ยวข้องกับ Ajax ทั้งหมด โดยค่าเริ่มต้นบริบทคือวัตถุที่แสดงถึงการตั้งค่า ajax ที่ใช้ในการโทร ( $.ajaxSettingsรวมเข้ากับการตั้งค่าที่ส่งไปยัง$.ajax) (... )

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

หรือใช้$.proxy:

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

หรือเก็บข้อมูลอ้างอิงถึงค่าthisนอกการเรียกกลับ:

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

ที่เกี่ยวข้อง


1
เมื่อฉันเริ่มเก่งขึ้นกับ JavaScript และสร้างโปรเจ็กต์ที่ซับซ้อนและใหญ่ขึ้นในที่สุดฉันก็คิดออกได้บ้าง แต่การได้เห็นคำตอบนี้ช่วยให้ฉันรู้ได้มากว่าสมมติฐานของฉันนั้นถูกต้องไม่ใช่แค่ทฤษฎีดังนั้นฉันจึงขอขอบคุณเป็นการส่วนตัวด้วยซ้ำ หากขัดต่อนโยบายความคิดเห็น SO! =)
JasonDavis

ฉันเห็นด้วย (และขอบคุณ) ตัวเลือกทั้งสามนี้ใช้ได้ผล ฉันไม่รู้เกี่ยวกับตัวเลือกบริบทของ ajax ข้อเสียเปรียบเล็กน้อยคือ IDE (Phpstorm) ของฉันไม่รู้จักตัวเลือกดังกล่าวช่วยแก้ไขปัญหาขอบเขตที่ตรวจพบในการปิด JS เช่นนี้ การเพิ่มกระดาษห่อหุ้มพร็อกซีจะทำให้คำเตือนหายไปดังนั้นบริบท: นี่ต้องเป็นเคล็ดลับที่ไม่รู้จักในรายการฮิวริสติกที่น่าจะเป็นแมมมอ ธ
scipilot

Ditto สำหรับตัวเลือกบริบท ทำงานได้อย่างสมบูรณ์แบบ
Anna_MediaGirl

ตัวอย่างยอดเยี่ยม!
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) {
                } 


});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.