MVC Razor $ .Ajax彼此不能很好地工作

时间:2016-08-02 17:20:26

标签: javascript ajax asp.net-mvc razor

我正在对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>

这是通过单击“刷新”

触发的javaScript
function 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,我猜它只是丢失了,从控制器返回的局部视图就是显示的内容。如果是这样,即使需要“成功:”部分吗?是否有更清晰的方式来表达这一点?

1 个答案:

答案 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和网络流量,以确认从部分视图操作返回的内容。