Ajax jQuery成功范围

27

我有一个对 doop.php 的 Ajax 调用。

    function doop(){
        var old = $(this).siblings('.old').html();
        var new = $(this).siblings('.new').val();

        $.ajax({
            url: 'doop.php',
            type: 'POST',
            data: 'before=' + old + '&after=' + new,
            success: function(resp) {
                if(resp == 1) {
                    $(this).siblings('.old').html(new);
                }
            }
        });

        return false;
    }

我的问题是$(this).siblings('.old').html(new);这一行没有按照预期执行。

谢谢,所有有用的评论/答案都将被投票支持。

更新: 似乎问题的一半是作用域(感谢帮助我澄清的答案),但另一半是我试图以同步方式使用ajax。 我已经创建了一个新的帖子。


8
哇哇哇哇哇。new 是一个保留字:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_keywords_as_of_ecmascript_2015 - Crescent Fresh
3
不要担心“new”,在我的代码中它被称为其他东西。只是为了让你们更容易理解代码才叫它“new”。 - Chris
3个回答

52

你应该像http://api.jquery.com/jQuery.ajax/中所示,使用上下文设置。

function doop(){
    var old = $(this).siblings('.old').html();
    var newValue = $(this).siblings('.new').val();

    $.ajax({
        url: 'doop.php',
        type: 'POST',
        context: this,
        data: 'before=' + old + '&after=' + newValue,
        success: function(resp) {
            if(resp == 1) {
                $(this).siblings('.old').html(newValue);
            }
        }
    });

    return false;
}

"this" 将被转移到成功范围并按预期起作用。


你真的不应该使用像 new 这样的保留字作为变量名。 - Tomalak
同意Nick的观点 - 这是正确的方法。请考虑,“将其保存在另一个变量中”的方法在多个按钮被点击或其他重复操作时,如果调用了函数“doop”则无法正常工作。 - Tim Holt
比所选答案更加灵活,对于我们的情况,每个项目的变量都必须是唯一的,这会导致代码膨胀。而这种方法只需要几个简短的字符,可以提供更多的灵活使用场景。 - oucil

26

首先,new保留字。您需要重命名该变量。

回答您的问题,是的,您需要在成功回调外部保存this变量,并在成功处理程序代码中引用它:

var that = this;
$.ajax({
    // ...
    success: function(resp) {
        if(resp == 1) {
            $(that).siblings('.old').html($new);
        }
    }
})

这就是所谓的闭包


嗯,奇怪,我尝试了与你所做的非常相似的东西,但是我使用了 var saveit = $(this); 却没有起作用。我现在会尝试这个.. 另外不用担心 "new",在我的代码中它被称为其他名称。 - Chris
@Chris:关于new,我也猜到了。 :) - Crescent Fresh
@Chris:关于闭包不起作用的问题,请确保 doop 本身是指向预期的 this。例如,如果您只是调用 doop(),那么 this 将只指向 window 对象。 - Crescent Fresh
好的,在闭包之后,我能够针对正确的this/that进行操作(我用show/hide测试过了,我知道它正在针对正确的东西)。然而,它没有更新HTML...我正在进行一些故障排除,并将在上面更新我的答案,请在有机会时回来查看,谢谢。 - Chris
现在我已经完成了故障排除,得出结论是问题的后半部分应该使用同步 AJAX 而不是异步。我将更新上面的问题并发布一个新的问题。 - Chris
你在 new 关键字上是正确的,但是在一个长列表中动态添加时,这会增加太多的代码膨胀。每个变量都必须是唯一的,而在下面的答案中,使用 context: this 只需执行一次,并且具有更灵活的用例。 - oucil

7
this被绑定到执行函数所应用的对象上。这可能是一些AJAX响应对象、全局对象(window)或其他东西(取决于$.ajax的实现)。
“我需要在进入$.ajax调用之前将$(this)捕获到变量中,然后将其作为参数传递给$.ajax调用吗?还是我需要将其传递给匿名成功函数?如果这样可以解决问题,在哪里将其传递给$.ajax呢?”
确实需要一种在定义success函数之前捕获this值的方法。创建闭包就是做到这一点的方法。您需要定义一个单独的变量(例如self):
function doop() {
    var old = $(this).siblings('.old').html();
    var new = $(this).siblings('.new').val();

    var self = this;

    $.ajax({
        url: 'doop.php',
        type: 'POST',
        data: 'before=' + old + '&after=' + new,
        success: function(resp) {
            if(resp == 1) {
                $(self).siblings('.old').html(new);
            }
        }
    });

    return false;
}
< p > 当调用success函数时,它将保留self的值,并且应该按您的预期行事。 < /p >

谢谢 +1。这与crescentfresh的答案相同,解决了“问题的一部分”..将更新问题并进行更多故障排除。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接