【问题标题】:MVC Razor $.Ajax not working well with each otherMVC Razor $.Ajax 不能很好地相互配合
【发布时间】:2016-12-08 04:25:29
【问题描述】:

我正在对 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,我猜它只是丢失了,而从控制器返回的部分视图就是显示的内容。如果是这样,是否需要“成功:”部分?有没有更简洁的方式来表达这一点?

【问题讨论】:

  • 你怎么知道一个列表是从RefreshTasksAndAlerts返回的?返回什么样的列表?
  • 我现在不知道,这是一个假设。我看到 $.Ajax 期望来自“Home/RefreshTasksAndAlerts”的某种响应 - 但该方法返回的是部分视图(“return PartialView("HomePage/_TasksAndAlerts", limduDataHelper.GetTasksAndAlertsModel") 部分返回的是在对 GetTasksAndAlertsModel 的调用中构建的列表。我试图了解 success: 函数是否真的在做任何事情,如果是,那么它在做什么?success:function 对我没有意义,我没有看不到模型的工作原理是返回局部视图。
  • 我错过了——返回的是这个类,其中包括几个列表public class TasksAndAlertsModel { public ArrayList alerts { get; set; } public List&lt;int&gt; unassignedAlerts { get; set; } public List&lt;int&gt; lockedByAnotherUserAlerts { get; set; } public List&lt;int&gt; lockedByCurrentUserAlerts { get; set; } public bool isOnDuty { get; set; } public bool isNotAPatient { get; set; } }

标签: javascript ajax asp.net-mvc razor


【解决方案1】:

在这种情况下,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 回调函数被执行。该函数只是将元素中的 HTML 替换为 id="TasksAndAlertsSection"。在您的情况下,它是第一次加载页面时呈现的实际 &lt;section&gt; 元素。因此,在第一次点击“刷新”后,页面上的 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 代码可能会遇到这种情况。

更正方法是将原始&lt;section&gt; 元素包含在原始视图中的&lt;div&gt; 元素中,该元素呈现页面((!)不在部分视图中)。所以,在你的主视图中,你会有这样的东西:

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

【讨论】:

  • 好的,我想我明白了。我不清楚控制器返回 HTML 流的部分——这是成功函数所期望的。非常感谢!我将仔细检查双节问题,现在我知道如何解决它了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
  • 2014-07-28
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多