【问题标题】:Second ajax result not appending to my div第二个 ajax 结果未附加到我的 div
【发布时间】:2018-05-31 17:44:33
【问题描述】:

我的函数有 2 个 ajax 请求。第二个 ajax 工作正常,但结果没有附加到我的 div 中。这是我的代码。任何帮助将不胜感激。

function load_candidates() {
  $.ajax({
    url: 'admin/requests/Get-Positions.php',
    method: 'POST',
    data: {
      id: id
    },
    dataType: 'json',
    success: function(result) {
      var textToInsert = '';

      $.each(result, function(key, value) {
        var position_id = value['id'];
        textToInsert += '<div class="card bg-primary text-center"><div class="card-body"><h4 class="text-white m-0" id="position">' + value['position'] + '</h4></div></div><br><div class="row">';
        $.ajax({
          url: 'admin/requests/Get-Candidate_Per_Position.php',
          method: 'POST',
          data: {
            position_id: position_id
          },
          dataType: 'json',
          success: function(data) {
            $.each(data, function(key, value) {
              textToInsert += '<div class="col-lg-4 col-sm-6 text-center mb-4"><h3>' + value['name'] + '</h3><p>' + value['candidate_number'] + '</p></div>';
            });
          }
        });
        textToInsert += '</div>';
      });
      $('#candidate_list').append(textToInsert);
    },
    error: function(xhr, status, error) {
      console.log(xhr.responseWithJSON)
    }
  });
}

【问题讨论】:

  • 您在从第二个 ajax 请求获得结果之前的附加。移动你的 $('#candidate_list').append(textToInsert);到第二个 ajax 成功调用
  • 这会有所帮助,但您也会在每次 AJAX 调用(不是完成)之后直接在循环中关闭 div,因此您将在 textToInsert 和然后 ASYNCHRONOUSLY 之后将附加迭代响应。
  • @Sagar 这就是我要回答的问题(并将textToInsert += '&lt;/div&gt;'; 移至同一个回调)。但还不够。从 $.each 可以看出他正在触发多个 AJAX 请求以获取每个职位的候选人。使用 async: false 可能会有所帮助,但您会遇到性能问题,因为您将连续触发多个请求并等待每个请求返回。我建议使用流控制库,例如async(特别是查看 async.map),或者更好的是 promises(如果需要,我可以提供代码示例)。
  • 谢谢你,我想我越来越近了。我得到了我想要的,但结果翻了一番。你觉得我哪里错了?谢谢btw sagar。
  • 我认为您有双重结果,因为您将textToInsert 附加到 div 的次数与您的职位一样多。

标签: javascript jquery ajax append


【解决方案1】:

这是 each() 对第一个响应的输出按正确顺序编写的:

  var textToInsert = '';

  $.each(result, function(key, value) {
    var position_id = value['id'];

    $.ajax({
      url: 'admin/requests/Get-Candidate_Per_Position.php',
      method: 'POST',
      data: {
        position_id: position_id
      },
      dataType: 'json',
      success: function(data) {
        textToInsert += '<div class="card bg-primary text-center"><div class="card-body"><h4 class="text-white m-0" id="position">' + value['position'] + '</h4></div></div><br><div class="row">';
        $.each(data, function(key, value) {
          textToInsert += '<div class="col-lg-4 col-sm-6 text-center mb-4"><h3>' + value['name'] + '</h3><p>' + value['candidate_number'] + '</p></div>';
        });
        textToInsert += '</div>';
        $('#candidate_list').html(textToInsert);
      }
    });
  });

【讨论】:

  • 在尝试这个作为@sagar 建议之后,我得到了双重结果。我不会退出去哪里出错。
  • 尝试将一些调试打印到循环内的控制台,以查看调用中是否有任何重复。简单的东西,比如 console.log("Requested "+position_id);
  • 实际上,@Benito 拥有它 - 您将附加到 textToInsert 字符串,然后每次将完整的字符串附加到 #condidate_list。您想在 #candidate_list 更新中使用 $('#candidate_list').html(textToInsert); 替换它
  • 感谢您的回答。我尝试放置一些调试日志,它看起来还不错。我得到位置 3、4 和 5。我想要的结果。没有重复或类似的东西。但仍然得到双倍的结果。
  • 我更新了答案中的代码以显示更新而不是追加
【解决方案2】:

在 ajax 请求完成之前附加结果。这意味着 TextToInsert 在那一刻仍然是空的。 它要么是 async:false 或将结果附加到 ajax 请求中

【讨论】:

  • 感谢您的回答,但在尝试了这两个选项后,我得到了双重结果。我得到了我想要的。唯一的问题是它翻了一番。
【解决方案3】:

感谢您的回答并给我一点时间。这对我帮助很大。谢谢你们。 .html(textToInsert) 的诀窍。我不知道为什么。我对 jquery 有点陌生。无论如何。谢谢你们。我真的很感激这一点。更多权力

【讨论】:

    【解决方案4】:

    这是一个使用 async 库的答案。当您必须执行一系列异步操作时,它非常有用。

    为了使用它,您必须在 HTML 代码中包含 async.js 或 async.min.js。您可以在 CDNJS 上找到脚本链接。

    这里我只使用async.map() 函数。这个想法是它为position_ids 数组中的每个项目执行load_candidate 函数(第二个参数)。所以所有的 AJAX 请求都会同时被触发。但它会等待所有请求完成,并将所有请求结果放入一个数组中。

    我知道使用这种库可能看起来有点吓人,但老实说,如果您必须编写某种复杂的代码,其中有许多异步调用,其中一些取决于以前的结果,这是值得的调查。

    我冒昧地将您的代码重构为更小、更具体的函数。我在浏览器中对其进行了测试,它可以正常工作,请记住,您的 id 变量必须在调用 load_candidates() 之前在某处定义。

    function load_position(id, cbSuccess, cbError) {
      $.ajax({
        url: 'admin/requests/Get-Positions.php',
        method: 'POST',
        data: {
          id: id
        },
        dataType: 'json',
        success: cbSuccess,
        error: cbError
      });  
    }
    
    function load_candidate(position_id, callback) {
      $.ajax({
        url: 'admin/requests/Get-Candidate_Per_Position.php',
        method: 'POST',
        data: {
          position_id: position_id
        },
        dataType: 'json',
        success: function(result) {
          callback(null, result);
        },
        error: function(xhr, status, error) {
          callback(new Error('Error in 2nd request: ' + xhr.responseText));
        }
      });
    }
    
    function ajax_error_handler(xhr, status, error) {
      console.log(xhr.responseText);
    }
    
    function load_candidates(id) {
    
      // Fires the 1st request
      load_position(id, function(result1) {
    
        // This extracts all position ids from the result of 1st request
        var position_ids = result1.map(function(value) {
          return value.id;
        });
    
        async.map(position_ids, load_candidate, function(err, result2) {
          // Abort on error
          // This will be called if ANY of the individual load_candidate() request fails
          if(err) {
            console.log(err);
            return;
          }
          // result2 is now an array of results of each AJAX request
    
          result1.forEach(function(value1, index1) {
    
            // Create your outer div
            var textToInsert = '';
            textToInsert += '<div class="card bg-primary text-center"><div class="card-body"><h4 class="text-white m-0" id="position">' + value1['position'] + '</h4></div></div><br><div class="row">';
            // append each result of 2nd request to that div 
            result2[index1].forEach(function(value2, key) {
              textToInsert += '<div class="col-lg-4 col-sm-6 text-center mb-4"><h3>' + value2['name'] + '</h3><p>' + value2['candidate_number'] + '</p></div>';
            });
    
            // then close it and append it to your list
            textToInsert += '</div>';
            $('#candidate_list').append(textToInsert);
    
          });
    
        });
      },
      ajax_error_handler);
    }
    
    // Your id variable has to be defined somewhere
    load_candidates(id);
    

    【讨论】:

      【解决方案5】:

      在您的第二个 ajax 请求中使用 async 属性并将其设置为 false。 AJAX 请求默认是异步的。他们不会等到响应来自服务器。

      将您的第二个 ajax 替换为以下内容:

      $.ajax({
      url: 'admin/requests/Get-Candidate_Per_Position.php',
      method: 'POST',
      data: {
          position_id: position_id
      },
      dataType: 'json',
      async: false,
      success: function(data) {
          $.each(data, function(key, value) {
              textToInsert += '<div class="col-lg-4 col-sm-6 text-center mb-4"><h3>' + value['name'] + '</h3><p>' + value['candidate_number'] + '</p></div>';
          });
      }});
      

      供您参考:

      1. http://api.jquery.com/jQuery.ajax/
      2. https://stackoverflow.com/a/1478322/3910232

      【讨论】:

      • 强制同步加载有点过头了,如果列表很长,可能会导致加载非常笨重...
      猜你喜欢
      • 2015-06-08
      • 2015-03-30
      • 2015-07-19
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 2013-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多