ajax函数仅在第一次调用时更新

时间:2015-10-17 22:22:49

标签: jquery ajax asp.net-mvc

我正在使用asp MVC 4和Jquery 1.10.2

我正在尝试更新部分视图中的表并调试Javascript似乎类似于Voodoo(至少对我而言)。

在第一次调用我的ajax函数时,更新按预期进行。任何后续通话都没有注册。

我已阅读了几篇文章和stackoverflow答案,其中包括设置cache = false,阅读开发人员工具中的网络标签,以了解正在发生的事情。

从第二个建议我可以看到第一个呼叫返回200状态响应,但第二个呼叫似乎什么也没做。

我已经在脚本中放置了警告框,在第一次调用时,所有都显示并且数据更新,但是在第二次调用时没有任何反应,为什么?

脚本

$("#resultsPerPage").change(function () {
    alert("pre")
    var selectedText = parseInt($(this).find(":selected").text())
    call_PropertyTable("", 1, selectedText);
    alert("post")
})

    //calls _PropertyTable Partial view
function call_PropertyTable(param, val, resultsPerPage) {
    $("#hdnCurrentPage").text(val);
    alert("pre-ajax")
    $.ajax({
        cache: false,
        url: "_PropertyTable",
        type: "get",
        data: { 'param': param, 'value': val, 'resultsPerPage': resultsPerPage },
        success: function (data) {
            $("#properties").html(data);
        }
    });
    alert("post-ajax")
}

视图

<div id="properties">
    @{Html.RenderPartial("_PropertyTable", Model);}
</div>

部分视图

//^^^other data not updating after first ajax call^^^
<select id="resultsPerPage" name="dataTables-example_length" aria-controls="dataTables-example" class="form-control input-sm">
                <option value="10" @{if (ViewBag.PageRange == 10) { ViewBag.Selected = "selected"; } else { ViewBag.Selected = ""; }} @ViewBag.Selected>10</option>
                <option value="25" @{if (ViewBag.PageRange == 25) { ViewBag.Selected = "selected"; } else { ViewBag.Selected = ""; }} @ViewBag.Selected>25</option>
                <option value="50" @{if (ViewBag.PageRange == 50) { ViewBag.Selected = "selected"; } else { ViewBag.Selected = ""; }} @ViewBag.Selected>50</option>
            </select> records per page

控制器

    public ActionResult _PropertyTable(string param, int value = 1, int resultsPerPage = 10)
    {
        ViewBag.PageRange = resultsPerPage;
        //other stuff
        return PartialView(properties);
    }

1 个答案:

答案 0 :(得分:1)

您的脚本正在用<select>替换id="resultsPerPage"元素,因此您附加处理程序的原始<select>元素不再存在,因此永远不会调用该事件。您需要使用.on()函数来使用事件委派。

替换

$("#resultsPerPage").change(function () {
  ....
});

$('#properties').on('change', '#resultsPerPage', function(){
  .....
});

修改

一些改进代码的建议。不清楚为什么你有一个单独的call_PropertyTable()函数,所以为了简单起见我刚刚结合这些。

var properties = $('#properties'); // cache elements your repeatedly refer to
properties.on('change', '#resultsPerPage', function() {
  var selectedText = $(this).val(); // all that's required
  $.ajax({
    cache: false,
    url: '@Url.Action("_PropertyTable")', // don't hard code your url's
    type: "get",
    data: { param: '', value: 1, resultsPerPage: selectedText}, // no need to quote property names
    success: function (data) {
      properties.html(data);
    }
});

或者更简单地使用$ .get()快捷方式

$.get('@Url.Action("_PropertyTable")', { param: '', value: 1, resultsPerPage: selectedText}, function(data) {
  properties.html(data);
});

使用视图模型而不是手动创建标记,并使用html帮助程序强烈绑定到模型属性

public class SampleViewModel
{
  public int PageRange { get; set; }
  public SelectList PageRangeList { get; set; }
  ....
}

public ActionResult _PropertyTable(string param, int value = 1, int resultsPerPage = 10)
{
  IEnumerable<int> pageRanges = new List<int>{ 10, 25, 50 };
  SampleViewModel model = new SampleViewModel()
  {
    PageRange = resultsPerPage,
    PageRangeList = new SelectList(pageRanges),
    ....
  };
  return PartialView(model);
}

并在局部视图中使用

@model SampleViewModel
....
@Html.DropDownListFor(m => m.PageRange, Model.PageRangeList)

请注意,不清楚为什么你需要在局部视图中生成下拉列表而不是在主视图中(在<div id="properties">元素之外)生成下拉列表,这样它就不会被它最初的html所取代。 (因此没有必要使用事件委托)。