我有一个包含子部分视图的视图(在主 _Layout.cshtml 视图中)。
我在主视图上有按钮(class = get-widgets),它应该调用控制器并检索一些数据以填充到子局部视图(_WidgetListPartial)中。这很好用......一次。点击事件注册似乎在第一次点击后会丢失,第二次和后续点击什么也不做。
我还注意到数据加载文本在调用运行时没有出现(它有一个 thread.sleep(2000) 来强制延迟)。
主视图中的代码:
索引.cshtml
@model MyApp.Models.WidgetViewModels.MainWidgetViewModel
@{ ViewBag.Title = "Widget Control Panel"; }
<div class="jumbotron">
<h1>@ViewBag.Title.</h1>
</div>
<div class="row">
<div class="col-md-6">
<h2>Widgets</h2>
<button class="btn btn-default pull-right get-widgets" data-loading-text="Loading ...">Refresh</button><br />
<div class="widgets">
@{Html.RenderPartial("_WidgetListPartial", Model.Widgets);}
</div>
<p>@Html.ActionLink("Create Widget", "Create", "Widget")</p>
</div>
</div>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.10.2.js")"></script>
<script>
$(document).ready(function () {
$(document).on('click', '.get-widgets', function (e) {
var $btn = $(this).prop('disabled', true);
$.ajax('@Url.Action("GetWidgets", "Desktop")').done(function (html) {
$('.widgets').html(html);
}).always(function () {
$btn.prop('disabled', false);
alert('You pressed refresh ...');
});
});
});
</script>
更新 **
经过进一步分析,看来 click 事件实际上正在触发。我已经通过在被调用的函数中添加一个javascript“alert”方法来证明这一点(见上文)。所以,现在看来,真正的问题是“$.ajax(...”调用没有在第二次和后续点击时执行(除非我在两次点击之间清除浏览器缓存)。
所以,我现在的问题似乎是“为什么“$.ajax”调用会基于缓存失败(或被抑制),而 $.ajax 调用实际上并不知道它需要从服务器检索的数据是否是是否会有所不同。
最终更新和解决方案
问题的原因似乎是,如果使用完全相同的 URL 再次执行 ajax 调用,它将“缓存”(在我的情况下它会这样做,因为结果的变化不是基于 ajax 调用本身的性质,但基于底层数据存储库可能已更改状态的事实)。因此,从浏览器的角度来看,来自 ajax 调用的请求是相同的。
答案是添加 $.ajaxSetup({ cache: false });
完整(工作版本)如下:
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.10.2.js")"></script>
<script>
$.ajaxSetup({ cache: false }); // NEEDED TO ENSURE THE AJAX CALL WILL RUN ON EVERY CLICK, AND NOT JUST THE FIRST
$(function () {
$(document).on('click', '.get-widgets', function (e) {
var $btn = $(this).prop('disabled', true);
$.ajax('@Url.Action("GetWidgets", "Desktop")').done(function (html) {
$('.widgets').html(html);
}).always(function () {
$btn.prop('disabled', false);
});
e.preventDefault();
});
});
</script>