JQuery ajax函数工作但无法正确返回变量

时间:2010-06-23 13:23:55

标签: php jquery ajax

我有一个正常运行的函数runAjax。不幸的是,我很难从ajax查询中返回我得到的值。

ajax函数将“contents”或“error”xml标记内的返回值赋给变量“result”。

如果我在ajax函数内警告结果变量,它会提醒正确的值(即如果内容中的xml值是“已发布”,则会发出警报)。

但是,如果我从runAjax函数提醒返回的值,它会提醒对象而不是上面示例中“已发布”的内部变量“result”的值。

function runAjax (data_obj){
  return $.ajax({
      url:"/ajax.php",
      dataType: "xml",
      data: data_obj,
      success: function(data) {
        // format result
        var xml;
        if (typeof data == "string") {
          xml = new ActiveXObject("Microsoft.XMLDOM");
          xml.async = false;
          xml.loadXML(data);
        } else {
          xml = data;
        }
        var result;
        if($("error",xml).text()){
          result = [$("error",xml).text()];
        } else{
          result = [
            $("contents", xml).text()
          ];
        }
      alert(result); //alerts the correct string for example "published"
      return result;
      }
    });
  }
  $('ul.content li span.changeable').click(function(e){
    e.preventDefault();
    var method_set = $(this).parent().attr("class");
    var id_set = $(this).parent().parent().find('li.id span').html();
    var user = $(this);
    var result = runAjax({method: method_set, id: id_set});
    alert(result); //alerts an object not published

  });

我确定它与我返回变量的方式有关但我无法弄明白。任何意见都会非常感激。

此致 路加

更新: 这是修改后的代码,感谢以下人员的所有输入:

  function runAjax (data_obj,callback){
    $.ajax({
      url:"/ajax.php",
      dataType: "xml",
      data: data_obj,
      success: function(data) {
        // format result
        var xml;
        if (typeof data == "string") {
          xml = new ActiveXObject("Microsoft.XMLDOM");
          xml.async = false;
          xml.loadXML(data);
        } else {
          xml = data;
        }
        var result;
        if($("error",xml).text()){
          result = [$("error",xml).text()];
        } else{
          result = [
          $("contents", xml).text()
          ];
        }
        if ( typeof(callback) == "function") {
          callback(result);
        }
      }
    });
  }
  $('ul.content li span.changeable').click(function(e){
    e.preventDefault();
    var method_set = $(this).parent().attr("class");
    var id_set = $(this).parent().parent().find('li.id span').html();
    var user = $(this);
    runAjax({
      method: method_set, 
      id: id_set
    },
    function(result){
      $(user).html(result.join('')); //this is instead of alert(result);
    }
    );

  });

7 个答案:

答案 0 :(得分:4)

根据docs

  

$ .ajax()函数返回它创建的XMLHttpRequest对象。

忽略从成功回调函数返回的任何返回值。

您需要将值放在比回调函数内部更宽的范围内定义的变量中(全局,或者最好在外部函数内)。

   var result;
   $.ajax({
       ....
       success : function(data) {
          ...
          result = ...;
       }
   });

或者更好的是:对成功回调函数中的返回值做任何你想做的事情,这将保持ajax调用的异步性质,这意味着你不需要等待调用回来。 / p>

在成功回调函数中进行处理意味着您知道自己有结果,如果将值放在变量中,则在您想要使用变量时,可能尚未为变量赋值。

在对此页面上的其他答案的评论中,您说:

  

但是我从多个其他函数调用runAjax函数,而不仅仅是我上面的代码示例中的函数,所以我需要返回的值而不是runAjax函数执行html替换

我会在runAjax函数中添加一个额外的参数,这是另一个可以从各种函数传递不同处理函数的回调函数。

function runAjax(data_obj, callback) {
    $.ajax({
        ...
        success : function(data) { 
            ...
            result = ...
            ...
            if ( typeof(callback) == "function") {
                callback(result);
            }
        }
    });
}

然后您可以将其称为

runAjax({method: method_set, id: id_set},
    function(result){
         alert(result);
    }
);

然后你可以在success函数中对数据进行泛型处理,但是回调函数中每次调用的自定义处理。

如果您确实需要等待呼叫,可以通过传递async选项来创建同步ajax呼叫:

 $.ajax({
    async:false,
    ....

答案 1 :(得分:2)

路,

基本上,使用回调部分的参数为$ .ajax()调用创建一个包装器函数(你当然可以在ajax调用中为任何有效参数提供参数。这里有一个快速演示:

function runAjax (data_obj, callback){
    $.ajax({
        url:"/ajax.php",
        dataType: "xml",
        data: data_obj,
        success: function(data) {
            if (data != null && callback !== null ) {
                callback(data);
            }
        }
    });
}

function callbackFunction (data) {
    // format result
    var xml;
    if (typeof data == "string") {
        xml = new ActiveXObject("Microsoft.XMLDOM");
        xml.async = false;
        xml.loadXML(data);
    } else {
        xml = data;
    }
    var result;
    if($("error",xml).text()){
        result = [$("error",xml).text()];
    } else{
        result = [
        $("contents", xml).text()
        ];
    }
    alert(result); //alerts the correct string for example "published"
    // do your DOM updates etc here
}

$('ul.content li span.changeable').click(function(e){
    e.preventDefault();
    var method_set = $(this).parent().attr("class");
    var id_set = $(this).parent().parent().find('li.id span').html();
    var user = $(this);
    runAjax({method: method_set, id: id_set}, callbackFunction);
});

希望这会有所帮助..

答案 2 :(得分:1)

路,

我认为你在函数的错误点分配了retrun值,你应该在最后的花括号之前有一个退出点。你在技术上返回结果作为$ .ajax()函数(一个XMHTTP对象)的返回值,而不是父方法。

试试这个:

function runAjax (data_obj){
    var returnValue;
    $.ajax({
        url:"/ajax.php",
        dataType: "xml",
        data: data_obj,
        success: function(data) {
            // format result
            var xml;
            if (typeof data == "string") {
                xml = new ActiveXObject("Microsoft.XMLDOM");
                xml.async = false;
                xml.loadXML(data);
            } else {
                xml = data;
            }
            var result;
            if($("error",xml).text()){
                result = [$("error",xml).text()];
            } else{
                result = [
                $("contents", xml).text()
                ];
            }
            alert(result); //alerts the correct string for example "published"
            returnValue = result;
        }
    });
    return returnValue;
}
$('ul.content li span.changeable').click(function(e){
    e.preventDefault();
    var method_set = $(this).parent().attr("class");
    var id_set = $(this).parent().parent().find('li.id span').html();
    var user = $(this);
    var result = runAjax({method: method_set, id: id_set});
    alert(result); //alerts an object not published

});

答案 3 :(得分:1)

你无法正确返回结果的原因是因为AJAX的异步特性(这就是第一个'A'代表的东西)。

对runAjax()的调用可能在AJAX操作完成之前很久就会返回,并且会调用“success”处理程序。 runAjax()调用返回对用于调用AJAX通信的XMLHttpRequest对象的引用。直接使用成功处理程序的返回值,因为它返回到$ .ajax()代码的内部工作。

一个合适的解决方案取决于你想对'结果'做什么 - 我猜测'警告(结果)'仅用于说明目的。

答案 4 :(得分:0)

尝试删除[]

  if($("error",xml).text()){
      result = $("error",xml).text();
  } else{
      result = $("contents", xml).text();
  }

答案 5 :(得分:0)

卢克 为了进一步完善我和Jim提供的答案,考虑到每个不同的调用结果解析位可能是一致的......

function runAjax (data_obj, callback){ 
    $.ajax({ 
        url:"/ajax.php", 
        dataType: "xml", 
        data: data_obj, 
        success: function(data) { 
            if (data != null && callback !== null ) { 
                // format result 
                var xml; 
                if (typeof data == "string") { 
                    xml = new ActiveXObject("Microsoft.XMLDOM"); 
                    xml.async = false; 
                    xml.loadXML(data); 
                } else { 
                    xml = data; 
                } 
                var result; 
                if($("error",xml).text()){ 
                    result = [$("error",xml).text()]; 
                } else{ 
                    result = [$("contents", xml).text()]; 
                } 
                callback(result); 
            } 
        } 
    }); 
} 

function callbackFunction (result) { 
    alert(result); //alerts the correct string for example "published" 
    // do your DOM updates etc here 
} 

$('ul.content li span.changeable').click(function(e){ 
    e.preventDefault(); 
    var method_set = $(this).parent().attr("class"); 
    var id_set = $(this).parent().parent().find('li.id span').html(); 
    var user = $(this); 
    runAjax({method: method_set, id: id_set}, callbackFunction); 
}); 

答案 6 :(得分:0)

您可以将ajax调用的成功处理为一个事件,该事件可以保留异步调用的优点,包括基于您调用的url的内容。

$('ul.content li span.changeable').ajaxSuccess(function(e, xhr, settings) {
  if (settings.url == '/ajax.php') {
    $(this).text('Triggered ajaxSuccess handler.');
    someglobalresultvariable = xhr.responseXML; // the xml of the response
    $(this).text(someglobalresultvariable);
  }
});

在这里,我假设你想根据点击的项目改变跨度内容文本。

注意:我替换了“已触发”文本消息,仅显示该示例。您可以决定如何处理结果。