MVC Razor$.Ajax彼此之间工作不好

MVC Razor $.Ajax not working well with each other

本文关键字:工作 彼此之间 Ajax Razor MVC      更新时间:2023-09-26

我正在维护MVC/Razor应用程序,并试图了解一些代码是如何工作的。网页上有一个刷新按钮,当用户单击它时,它应该刷新任务列表。它似乎被破坏了,但在试图追踪它是如何工作的过程中,我遇到了Ajax做事的方式和MVC处理部分视图的方式之间的冲突。我有点怀疑代码最初是为Ajax调用编写的,但当他们后来决定使用MVC时,他们只是用部分视图方法替代了它;但我对这是如何运作的还不够了解。

这是部分视图(名为"_TasksAndAlerts.cs.html"),其中包含一个"刷新"按钮——

@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("TasksAndAlertsSSection")"部分中的所有内容。但是从"刷新任务和警报"返回的是一个列表,而不是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,我猜它只是丢失了,从控制器返回的部分视图就是显示的内容。如果是这样的话,是否还需要"成功"部分?有没有更干净的方式来表达这一点?

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>元素。因此,在第一次点击"刷新"后,页面上的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和网络流量,以确认部分视图操作返回的内容。