MVC 视图数据不会在 jQuery Post 上更新,但会在单击表单提交按钮时更新

MVC View data doesn't update on jQuery Post but does on Form submit button click

在我看来,我有一个 DropDownListFor,select 是服务器上日期列表中的一个日期。当我使用 jQuery .on "change" $.post 操作到 post 我 select 返回控制器的日期时,它正确地从服务器并更新视图模型,但它不会显示在浏览器中。它保留以前的值。但是,如果我改为单击视图表单中的提交按钮,它会使用来自服务器的数据正确更新数据字段。我如何 post 下拉列表 selection 确定我的数据字段是否正确更新。

有人对我如何让 jQuery post 更新视图中的数据字段而不是保留以前的值有任何建议吗?

这是我的视图模型:

    public class HtmlData
    {
        public string FileDateListSelection { get; set; }
        public List<SelectListItem> FileDateList { get; set; }
        public string ServerData { get; set; }

        public HtmlData(string selectedDate, List<SelectListItem> fileDateList, string serverData)
        {
            FileDateListSelection = selectedDate;
            FileDateList = fileDateList;
            ServerData = serverData;
        }
    }

这是我的观点:

@model MvcJqueryTest.Models.HtmlData

@using (Html.BeginForm("SubmitButtonDateChange", "Home", FormMethod.Post, new { id = "dateSelectionForm" }))
{
    <div class="row">
        <div class="col-md-4">
            <div id="dateList">
                @Html.DropDownListFor(m => m.FileDateListSelection, Model.FileDateList)
            </div>
        </div>
        <div class="col-md-2">
            <div id="buttons">
                <input type="submit" name="submit" value="Fetch" id="fetchButton" />
                <input type="submit" name="submit" value="Reset" id="resetButton" />
            </div>
        </div>
    </div>
}

<div class="row">
    <div class="col-md-8">
        <br />
        <h3>@Model.ServerData</h3>
        <br />
    </div>
</div>

<script type="text/javascript">
    $('#FileDateListSelection').on("change", function () {
        var menuDateSelected = $('#FileDateListSelection').val();
        $.post(
            '@Url.Action("JqueryDateChange", "Home")',
            { selectedDate: menuDateSelected },
            function (response) {
            }
        );
    });
</script>

这是我的家庭控制器方法:

        public ActionResult Index(string dateString)
        {
            DateTime compareTime = DateTime.Today;

            if (!string.IsNullOrEmpty(dateString))
                compareTime = DateTime.Parse(dateString);

            string quote = "Now is the winter of our discontent";

            if (compareTime < DateTime.Today)
                quote = "Made glorious summer by this sun of York";

            string selectedDate = FileOperations.GetDateList(compareTime, out List<SelectListItem> dateList);

            HtmlData hd = new HtmlData(selectedDate, dateList, quote);

            return View(hd);
        }

        [HttpPost]
        public ActionResult SubmitButtonDateChange(string FileDateListSelection, string submit)
        {
            string selectedDate = FileDateListSelection;

            if (submit.Equals("Reset", StringComparison.OrdinalIgnoreCase))
                selectedDate = DateTime.Now.Date.ToString("d", CultureInfo.GetCultureInfo("en-US"));

            return RedirectToAction("Index", "Home", new { dateString = selectedDate });
        }

        [HttpPost]
        public ActionResult JqueryDateChange(string selectedDate)
        {
            return RedirectToAction("Index", "Home", new { dateString = selectedDate });
        }

GetDateList 方法只是 returns 下拉列表文件夹中文件日期的 SelectListItem 列表,selects 一个日期作为列表中的 selected 项目.如果 selected 日期早于今天,视图中包含视图模型的“ServerData”属性 的 h3 标记显示“Now is the winter of our discontent”。如果 selected 日期是今天午夜之后,h3 标签会显示“Made grorious summer by this sun of York”。

当我更改下拉列表中的 selection 时,将执行 JqueryDateChange 控制器方法,并使用 selected 日期作为参数对 Index 方法执行 RedirectToAction,其中填写具有“ServerData”属性 正确数据的视图模型。但是模型中的“ServerData”值并没有显示在浏览器中。它始终保留以前的值,即使当我在视图中的 <h3>@Model.ServerData</h3> 上设置中断时我可以在调试器中看到正确的值。

当我单击视图窗体中的“获取”或“重置”按钮时,SubmitButtonDateChange 控制器方法将执行,并且还会使用 selected 日期作为参数对 Index 方法执行 RedirectToAction。这也用“ServerData”属性 的正确值填充视图模型,但随后它在浏览器中正确更新,显示基于下拉列表 selection 的新值。

我最初使用 $.ajax 来 post 新的下拉列表建议,但有同样的问题。我还尝试将“@Model.ServerData”移动到表单的大括号内,但这也无济于事。我找到了一些我认为可能有用的关于 ModelState 的信息,但是当我在调试器中查看它时,它只有一对 key/value 用于 dateString 参数,所以我看不出如何使用它来修复问题。

我认为 AJAX 解决方案足以满足您的情况。您可以执行以下操作。

首先,为您的 HTML 元素定义一个唯一的 id,您将在其中显示 ServerData:

的值
<div class="row">
    <div class="col-md-8">
        <br />
        <h3 id="serverDataID">@Model.ServerData</h3>
        <br />
    </div>
</div>

然后您需要像这样定义 AJAX 调用:

<script type="text/javascript">
    $('#FileDateListSelection').on("change", function () {
        var menuDateSelected = $('#FileDateListSelection').val();
        
        var json = {
            menuDateSelected: menuDateSelected
        };

        var options = {};
        options.url = "@Url.Action("JqueryDateChange", "Home")";
        options.type = "POST";
        options.data = {"json": JSON.stringify(json)};
        options.dataType = "json";
        options.success = function (data) {
            if (data.status == "true") {
                $('#serverDataID').html(data.quoteString);
            }
            else {
                alert("Some Error");
            }
        };
        options.error = function (data) {
            alert("Error while calling function");
            console.log(data);
        };

        $.ajax(options);
    });
</script>

并且您的 Controller 方法将 return 一个 JsonResult 来处理回调:

using System.Web.Script.Serialization;

[HttpPost]
public JsonResult JqueryDateChange(string json)
{
    var serializer = new JavaScriptSerializer();
    dynamic jsondata = serializer.Deserialize(json, typeof(object));
    //Get your variables here from AJAX call
    var dateString = Convert.ToString(jsondata["menuDateSelected"]);
    DateTime compareTime = DateTime.Today;

    if (!string.IsNullOrEmpty(dateString))
        compareTime = DateTime.Parse(dateString);

    string quote = "Now is the winter of our discontent";

    if (compareTime < DateTime.Today)
        quote = "Made glorious summer by this sun of York";

    string selectedDate = FileOperations.GetDateList(compareTime, out List<SelectListItem> dateList);   
    return Json(new { status = "true", quoteString = quote }, JsonRequestBehavior.AllowGet);
}