【问题标题】:Retrieving the index of deferred jquery ajax request using .when.apply()使用 .when.apply() 检索延迟的 jquery ajax 请求的索引
【发布时间】:2016-12-01 16:10:31
【问题描述】:

我有一个对象列表,我想使用 ajax 帖子传递给部分视图的未知数量。局部视图只是一个基本表,它在每个局部视图中显示我希望的数据。我可以很好地做到这一点,问题是,我希望每个部分视图都位于单独的 div 元素中,因为我想合并拖放,我认为为此我需要知道拖放的 div id? (如果我在这里错了,请纠正我)。

这意味着我需要首先动态创建 div 并使用循环 .each() 为它们分配它们的 id 并增加 id 号。我知道我需要在这里使用 .append() 函数,它可以完美地创建 div,正确命名它们。

现在的问题是,我希望对创建的每个 div 元素的部分视图操作执行 ajax 发布请求,并且我想将 html 更改为部分视图响应。我意识到 ajax 调用是异步的,这就是为什么一开始只有最后一个 div 正在更新,所以我将所有请求放在一个数组中并使用 .when.apply().then() 来更改 div 的 html。但是我不知道要更改的 div 的 id;我想如果我可以获取数组中当前项的索引,我可以使用它,但我不知道如何获取它。

有人可以看看我的代码并告诉我是否过于复杂,或者我如何获得我需要为其设置 html 的 div 的索引?

    <script type="text/javascript">
    $(document).ready(function () {
        var modelData = [@Html.Raw(Json.Encode(Model.mappings))][0];
        var divid;
        var ajaxrequests = [];
        $.each(modelData, function (i, item) {
            divid = 'header' + i;
            $('#HeaderData').append('<div id="' + divid + '">Hello</div>');
            ajaxrequests.push($.ajax({
                url: "HeaderFieldMapping",
                type: "POST",
                data: JSON.stringify(item),
                contentType: "application/json; charset=utf-8",
                dataType: "html"
            }));
        });
        $.when.apply($, ajaxrequests).then(function (resultdata) {
            divid = 'header' + [index???];
            $('#' + divid).html(resultdata);
        });
    });
</script>

编辑之前的尝试结果是它不断覆盖最后一个 div 元素

    <script type="text/javascript">
    function rowDropHandler(args) {
        var item = args.data[0];
        alert(item);
    }
    $(document).ready(function () {
        var modelData = [@Html.Raw(Json.Encode(Model.mappings))][0];
        var divid;
        var ajaxrequests = [];
        var intnum = 0;
        $.each(modelData, function (i, item) {
            divid = 'header' + i;
            $('#HeaderData').append('<div id="' + divid + '">Hello</div>');
            ajaxrequests.push($.ajax({
                url: "HeaderFieldMapping",
                type: "POST",
                data: JSON.stringify(item),
                contentType: "application/json; charset=utf-8",
                dataType: "html",
                success: function(resultdata){
                    $('#' + divid).html(resultdata);
            }
            }));
        });
        $.when.apply($, ajaxrequests).then(function (resultdata) {
            alert('done' + resultdata);
        });
    });
</script>

【问题讨论】:

  • 要处理单个 AJAX 请求,请在每个 $.ajax 调用中添加一个 success 处理函数。然后,您可以为每个响应创建嵌套在 div 中的所需 table
  • 我试过了,但没有一个 div 更新。我使用警报告诉我他们何时完成并且警报显示但没有任何 div 更改。这就是为什么我将更改 div html 的代码放在.then() 函数中。现在最后一个会改变,但其他都不会改变,因为 divid 是创建的最终 div 的 id。
  • 您能否更新问题以显示您在这种情况下的尝试。请注意,如果您使用.html(),那么每个后续请求都会覆盖前一个请求。 append() 在这种情况下会更合适。
  • 我已经更新了之前的尝试@RoryMcCrossan。
  • 谢谢。问题确实是因为您使用了html()。使用$('#' + divid).append(resultdata); 而不是.html()。您也可以删除$.when 电话

标签: jquery ajax asp.net-mvc-5 jquery-deferred


【解决方案1】:

在您的第一个基于$.when 的版本中,您将在arguments 伪数组中为每个promise 获得一个单独的条目。这些条目中的每一个都将是 success 处理程序的三个标准参数的数组。

因此您可以简单地遍历该数组并填写您的 HTML:

$.when.apply($, ajaxrequests).then(function() {
    [].forEach.call(arguments, function(result, index) {
        var divid = 'header' + index;
        var resultdata = result[0];
        $('<div>', {id: divid, html: resultdata}).appendTo('#HeaderData');
    });
});

附言考虑使用Array.prototype.map 将您的元素数组转换为promise 数组而不是.each / push 循环:

var ajaxrequests = modelData.map(function(item, index) { // NB: index unused
    return $.ajax({
        url: "HeaderFieldMapping",
        type: "POST",
        data: JSON.stringify(item),
        contentType: "application/json; charset=utf-8",
        dataType: "html"
    });
});

【讨论】:

  • 那么,这是使用数组的索引来获取添加它们的顺序,这会使“除数”相同吗?我假设我仍然需要$.each 来循环遍历我的模型数据以首先创建 div?我将不得不查找 Array.prototype.map 看看这对我有什么帮助。
  • 您可以推迟 div 的创建并将其放在 .forEach 调用中 - 我会相应地更新(是的,数组的索引最终使除数相同)
  • 啊,我看到了 Array.map 现在做了什么。它为数组中的每个项目运行一个函数。谢谢你。
  • @HollyMarieBatchelor 我为.map添加了一个示例
  • 我希望我能不止一次地支持这个答案!它很干净,易于理解并且很有效(除了一个额外的支架)非常感谢您的帮助;我整天都在研究这个问题,用我能想到的各种方式搜索它,但无济于事。显然我没有寻找正确的东西,但我又一次不知道我在寻找什么。
【解决方案2】:

您的第二批代码更接近于工作。您只需将 Ajax 调用代码包装在 IIFE 中,以在成功触发时保持除数的值。在这种情况下,您不需要承诺:

例如像这样:

$(function() {  // <<< Shortcut for DOM ready handler
  var modelData = [@Html.Raw(Json.Encode(Model.mappings))][0];
  var divid;
  var intnum = 0;
  $.each(modelData, function(i, item) {
    divid = 'header' + i;
    $('#HeaderData').append('<div id="' + divid + '">Hello</div>');
    (function(divid) {
      $.ajax({
          url: "HeaderFieldMapping",
          type: "POST",
          data: JSON.stringify(item),
          contentType: "application/json; charset=utf-8",
          dataType: "html",
          success: function(resultdata) {
            $('#' + divid).html(resultdata);
          }
        )
      }(divid);
    });
  });
});

【讨论】:

  • 这太复杂了 - 变量 i 已经绑定在闭包中,因此最简单的解决方法是将 divid = 'header' + i 的计算放在回调中而不使用 IIFE。跨度>
  • 太棒了!我以前从未听说过IIFE! (web/jquery 的新手)代码中的括号给了我一些 jip,但最终还是把它整理出来了。我在源代码中找不到 div 元素,但当我尝试构建 drop 函数时,我会弄清楚为什么!再次感谢! (也感谢 DOM 准备好的快捷方式!)
  • @HollyMarieBatchelor IIFE 完全没有必要(尽管它避免了重复一行微不足道的代码)。或者,将 header div 的创建也推迟到回调内部。
  • @Alnitak:非常感谢。但为什么要把它放在那里开始。这个问题有多种答案。我只是去了一个容易理解的地方:)
  • 考虑将var divid = 'header' + i 放在success 回调中将完全避免IIFE,使其更容易跟踪
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多