使用.when.apply()检索延迟的jquery ajax请求的索引

时间:2016-12-01 16:10:31

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

我有一个对象列表,其中未知的数量我想通过ajax帖子传递给部分视图。局部视图只是一个基本表,在每个局部视图中显示数据的方式。我可以做得很好,问题是,我希望每个局部视图都在单个div元素中,因为我想要拖放并且我想为此我需要知道drop的div id? (如果我在这里错了,请纠正我。)

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

现在问题是我希望对我创建的每个div元素的部分视图操作执行ajax post请求,并且我想将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>

2 个答案:

答案 0 :(得分:2)

在您的第一个基于$.when的版本中,您将在arguments伪数组中为每个承诺获得单独的条目。这些条目中的每一个依次是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');
    });
});

P.S。考虑使用Array.prototype.map将您的元素数组转换为promises数组而不是.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"
    });
});

答案 1 :(得分:1)

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

e.g。像这样的东西:

$(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);
    });
  });
});