我正在对MVC / Razor应用程序进行维护,并试图了解一些代码的工作原理。网页上有一个刷新按钮,当用户点击它时,它应该刷新一个任务列表。它似乎被破坏了,但是在试图追踪它是如何工作的时候,我遇到了Ajax做事的方式与MVC做局部视图的方式之间的冲突。我有点怀疑代码最初是为Ajax调用编写的,但是当他们后来决定转向MVC时,他们只是用部分视图方法来覆盖它;但我对于如何确定这一点并不够了解。
这是包含“刷新”按钮的部分视图(名为“_TasksAndAlerts.cshtml”) -
@model TasksAndAlertsModel
<section class="block-1-2 pull-right" id="TasksAndAlertsSection">
<div class="inline">
<h3>tasks/alerts<span>@Model.alerts.Count</span></h3>
</div>
<div class="inline" style="margin: 19px 0px 0px 0px;">
<!-- this is the "refresh" button, visually it's an icon -->
<button style="width: 20px; height: 20px;" id="refreshTasksAndAlerts" class="k-button"
onclick="RefreshTasksAndAlertsAjaxCall(0);return false;">
<span style="position: relative; left: -6px; top: -6px;" class="k-icon k-si-refresh"></span>
</button>
</div>
<ul class="tasks" style="overflow: auto; height: 404px">
@for (int a = 0; a < Model.lockedByCurrentUserAlerts.Count; a++)
{
@Html.Raw(HttpUtility.HtmlDecode(Model.alerts[Model.lockedByCurrentUserAlerts.ElementAt(a)].ToString()));
}
@for (int b = 0; b < Model.unassignedAlerts.Count; b++)
{
@Html.Raw(HttpUtility.HtmlDecode(Model.alerts[Model.unassignedAlerts.ElementAt(b)].ToString()));
}
@for (int c = 0; c < Model.lockedByAnotherUserAlerts.Count; c++)
{
@Html.Raw(HttpUtility.HtmlDecode(Model.alerts[Model.lockedByAnotherUserAlerts.ElementAt(c)].ToString()));
}
</ul>
</section>
这是通过单击“刷新”
触发的javaScriptfunction RefreshTasksAndAlertsAjaxCall(alertID) {
$.ajax({
type: "GET",
url: siteRoot + "Home/RefreshTasksAndAlerts/?t=" + Math.random(),
success: function (response) {
$(document.getElementById("TasksAndAlertsSection")).html(response);
},
error: function (response) {
//alert(response.responseText);
}
});
}
从阅读$ .ajax,我得到的印象是成功值的内容将替换“getElementById(”TasksAndAlertsSection“)”部分中的所有内容。但是从“RefreshTasksAndAlerts”返回的是一个列表,而不是HTML。虽然可以使用某种javaScript处理列表,但我认为没有任何事情可以实现。
这是从javaScript
调用的控制器代码public PartialViewResult RefreshTasksAndAlerts(int? id)
{
LIMDUEntities db = closedKeyEntity;
return PartialView("HomePage/_TasksAndAlerts", limduDataHelper.GetTasksAndAlertsModel(HOURS_UNTIL_TASKS_SHOULD_BE_REASSIGNED, db));
}
'return'中引用的代码是一段很长的代码,最终返回一个列表(我只是展示了它的一部分,因为它构建的不是我的问题):
public TasksAndAlertsModel GetTasksAndAlertsModel(int HOURS_UNTIL_TASKS_SHOULD_BE_REASSIGNED, LIMDUEntities db)
{
ArrayList alerts = new ArrayList();
TasksAndAlertsModel TAAM = new TasksAndAlertsModel();
TAAM.alerts = alerts;
TAAM.unassignedAlerts = UnassignedIndexes;
TAAM.lockedByAnotherUserAlerts = lockedByAnotherUserIndexes;
TAAM.lockedByCurrentUserAlerts = lockedByCurrentUserIndexes;
return TAAM;
}
我对实际发生的事情感到困惑 - 我认为这两种方法相互冲突。由于返回$ .Ajax的数据不是HTML,我猜它只是丢失了,从控制器返回的局部视图就是显示的内容。如果是这样,即使需要“成功:”部分吗?是否有更清晰的方式来表达这一点?
答案 0 :(得分:0)
在这种情况下,MVC Razor和$ .Ajax之间没有冲突。您的控制器操作RefreshTasksAndAlerts
呈现部分视图(如果您愿意,则呈现页面的一部分)并仅返回HTML代码(没有任何类型的列表)。在你的情况下会返回这样的内容:
<section class="block-1-2 pull-right" id="TasksAndAlertsSection">
<div class="inline">
.... other html here ....
</div>
</section>
JavaScript函数RefreshTasksAndAlertsAjaxCall
调用/调用控制器操作。当返回响应时(来自控制器的上述HTML代码),执行success
回调函数。该函数只是用id="TasksAndAlertsSection"
替换元素中的HTML。在您的情况下,它是第一次加载页面时呈现的实际<section>
元素。所以在第一次点击&#34;刷新&#34;页面上的html看起来像:
<section class="block-1-2 pull-right" id="TasksAndAlertsSection">
<section class="block-1-2 pull-right" id="TasksAndAlertsSection">
<div class="inline">
.... other html here ....
</div>
</section>
</section>
现在,这是一个问题,因为您现在在页面上有两个具有相同ID的元素,这是无效的,尽管浏览器会容忍这个并且会像您期望的那样呈现页面,更多 - 减。您的JavaScript代码可能会遇到这种情况的问题。
更正是将原始<section>
元素包含在原始视图中的<div>
元素中,该元素呈现页面((!)不在局部视图中)。所以,在你的主视图中,你有类似的东西:
<div id="SectionParent">
.... render partial view the same way you are doing it now ....
</div>
这将生成如下的html输出:
<div id="SectionParent">
<section class="block-1-2 pull-right" id="TasksAndAlertsSection">
<div class="inline">
.... other html here ....
</div>
</section>
</div>
将success
回调更新为:
success: function (response) {
$(document.getElementById("SectionParent")).html(response);
},
它应该都很好。
您可以在浏览器中使用开发工具,并检查页面html和网络流量,以确认从部分视图操作返回的内容。