Ajax-функция JQuery работает, но не может правильно вернуть переменную - PullRequest
1 голос
/ 23 июня 2010

У меня есть функция runAjax, которая работает правильно.К сожалению, я изо всех сил пытаюсь вернуть значение, которое я получаю из запроса ajax.

Функция ajax присваивает возвращаемое значение внутри xml-тегов "contents" или "error" переменной "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 ]

4 голосов
/ 23 июня 2010

Согласно документам

Функция $ .ajax () возвращает созданный ею объект XMLHttpRequest.

Любое возвращаемое значение, которое вы возвращаете из функции обратного вызова, игнорируется.

Вам необходимо поместить значение в переменную, определенную в более широкой области видимости, чем внутри функции обратного вызова (глобальной или предпочтительно внутри внешней функции).

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

Или, что еще лучше: делайте все, что хотите с возвращаемым значением внутри функции обратного вызова success, это сохранит асинхронный характер вызова ajax и означает, что вам не нужно ждать возврата вызова.

Выполнение обработки в функции обратного вызова success означает, что вы знаете, что у вас есть результаты, если вы поместите значение в переменную, переменной может еще не быть присвоено значение к тому времени, когда вы захотите ее использовать.

В комментарии к другому ответу на этой странице вы говорите:

однако я вызываю функцию 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);
    }
);

Затем вы можете выполнять общую обработку данных в функции успеха, но пользовательскую обработку для каждого вызова в функции обратного вызова.

Если вам действительно нужно дождаться вызова, вы можете создать синхронный вызов ajax, передав опцию async:

 $.ajax({
    async:false,
    ....
2 голосов
/ 23 июня 2010

Люк

По сути, создайте функцию-обертку для вашего вызова $ .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);
});

надеюсь, это поможет ..

1 голос
/ 23 июня 2010

Причина, по которой вы не можете получить результат, возвращаемый правильно, заключается в асинхронном характере AJAX (это то, что обозначает первый 'A').

Вызов runAjax (), вероятно, возвращается задолго до завершения операции AJAX и вызова обработчика success. Вызов runAjax () возвращает ссылку на объект XMLHttpRequest, который использовался для вызова связи AJAX. Возвращаемое значение из обработчика успеха не может быть использовано вами напрямую, поскольку оно вернулось к внутренней работе кода $ .ajax ().

Подходящее решение будет зависеть от того, что вы хотите сделать с «результатом» - я предполагаю, что «оповещение (результат)» предназначено только для иллюстрации.

1 голос
/ 23 июня 2010

Люк,

Я думаю, что вы присваиваете значение повторного запуска в неправильной точке функции, у вас действительно должна быть единственная точка выхода перед последней фигурной скобкой.вы возвращаете результат технически как возвращаемое значение функции $ .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

});
0 голосов
/ 23 июня 2010

Вы можете обработать успешность вызова 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);
  }
});

Здесь я делаю дикое предположение, что вы хотите изменить текст содержимого диапазона на основе выбранного элемента.

ПРИМЕЧАНИЕ. Я заменил «запущенное» текстовое сообщение и показываю это только в качестве примера. Вы можете решить, как вы хотите обработать результат.

0 голосов
/ 23 июня 2010

Люк, Для дальнейшего уточнения ответов, предоставленных мной и Джимом, учитывая, что бит разбора результата, вероятно, будет согласованным для каждого из различных вызовов ...

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); 
}); 
0 голосов
/ 23 июня 2010

попробуйте удалить [ и ]

  if($("error",xml).text()){
      result = $("error",xml).text();
  } else{
      result = $("contents", xml).text();
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...