通过 Ajax Post 使用模型更改更新视图 - MVC3

Posted

技术标签:

【中文标题】通过 Ajax Post 使用模型更改更新视图 - MVC3【英文标题】:Updating View with Model changes via Ajax Post - MVC3 【发布时间】:2011-10-14 05:35:59 【问题描述】:

我正在尝试使用 Ajax(我认为)调用来更新我的模型值,然后让该新值反映在视图中。目前我只是将其用于测试目的。

概述如下:

型号

public class MyModel

    public int Integer  get; set; 
    public string Str  get; set; 

控制器

    public ActionResult Index()
    
        var m = new MyModel();
        return View("Test1", m);
    

    [HttpPost]
    public ActionResult ChangeTheValue(MyModel model)
    
        var m = new MyModel();
        m.Str = model.Str;
        m.Str = m.Str + " Changed! ";
        m.Integer++;

        return View("Test1", m);

    

查看

  @model Test_Telerik_MVC.Models.MyModel
@using Test_Telerik_MVC.Models
@
    ViewBag.Title = "Test1";
    Layout = "~/Views/Shared/_Layout.cshtml";

<h2>
    Test1</h2>
@if (false)

    <script src="~/Scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
    <script src="~/Scripts/jquery-ui.min.js" type="text/javascript"></script>

<h2>
    ViewPage1
</h2>

<div>
    <input type="button" onclick="changeButtonClicked()" id="changeButton" value="Click Me!" />
    <input type="text" value="@Model.Str" class="txt" id="str" name="Str"/>
    <div></div>
</div>

<script type="text/javascript">

    function changeButtonClicked() 
        var url = '@Url.Action("ChangeTheValue", "Test1")';
        var data = '@Model';
        $.post(url, data, function (view) 
            $("#Str").value = '@Model.Str';
        );
    

</script>

基本上,视图会渲染一个带有文本框的按钮。我的唯一目的是在文本框中简单地显示我的模型(Str 属性)的值。

我尝试了 changeButtonClicked() 函数的各种组合,但均无济于事。 Test1 是我的控制器的名称。我不明白的是,当我调试它时,控制器操作会触发并正确设置我的值。如果我在输入标签的“@Model.Str”部分放置一个断点,它会告诉我我的@Model.Str 等于 Changed!哪个是对的。但是,一旦我的成功函数在 javascript 中触发,该值就会恢复为原始值。

我可以通过更改要提交的输入类型并将其包装在 @Html.BeginForm() 部分中来使其工作,但我想知道是否/如何这样做?还是提交是完成它的唯一方法?

谢谢

【问题讨论】:

【参考方案1】:

在 jQuery 中,设置输入值的第一件事是使用:

$("#Str").val(@Model.Str);

接下来我们来看看控制器。在POST 操作结果中,您将在 AJAX 调用中返回整个视图。这意味着所有 HTML、脚本引用和 JavaScript 都将在您的 jQuery 发布请求中返回。由于您尝试更新的只是名为 Str 的输入的值,因此我只会将该值作为 JSON 返回,而不是其他任何内容。

[HttpPost]
public ActionResult ChangeTheValue(MyModel model)

    var m = new MyModel();
    m.Str = model.Str;
    m.Str = m.Str + " Changed! ";
    m.Integer++;

    return Json(m.Str);


接下来我会将您的 HTML 输入放在 &lt;form&gt; 中,这样您就可以让 jQuery 为您序列化您的模型,然后您可以将您的 jQuery 邮政编码更改为:

function changeButtonClicked() 
    var url = '@Url.Action("ChangeTheValue", "Test1")';
    $.post(url, $('form').serialize(), function (view) 
        $("#Str").val(view);
    );

序列化所做的只是将表单中的输入编码为字符串,如果所有内容都正确命名,ASP.NET 会将其绑定回您的模型。

如果您需要让您的路由同时处理 AJAX 调用和完整请求,您可以使用 ASP.NET 的 IsAjaxRequest 函数来测试请求并根据请求是否为 AJAX 返回不同的结果。你会在你的控制器中做这样的事情:

[HttpPost]
public ActionResult ChangeTheValue(MyModel model)

    var m = new MyModel();
    m.Str = model.Str;
    m.Str = m.Str + " Changed! ";
    m.Integer++;

    if (Request.IsAjaxRequest) 
        return Json(m.Str);
    
    else 
        return View("Test1", m);
    

在上面的ActionResult 中,您正在执行您之前所做的一切,但现在正在测试请求类型,如果它是 AJAX,您将返回字符串值的 JSON 结果。如果请求不是来自 AJAX 调用,则返回完整的视图(HTML、脚本等)以显示在浏览器中。

我希望这对您有所帮助,并且是您正在寻找的。​​p>

【讨论】:

伙伴,太棒了。稍后我将介绍您所说的内容并让您知道。我希望你所描述的确实有效。干杯 好的,我已经成功了。正如您所说,JSON 是在这种情况下要走的路。但是,专门设置值仍然意味着我的“模型”对象永远不会包含更新的值?因此,如果我在另一个事件中引用它(比如在这个事件被触发之后),@Model.Str 实际上并不包含新值。为了实现这一点,我需要提交吗?感谢您到目前为止的回答。它确实回答了我最初的问题。 如果您想获取输入的最新值,您需要从输入本身获取它们,您可以使用 jQuery $(#Str).val() 来获取。否则,如果您在 javascript 代码中的其他地方使用 Model.Str,则 Model.Str 的值会在页面首次加载时设置,并且永远不会更新,除非您进行整页刷新。 还想补充一点,您可以在 Json 请求 return Json(m) 中返回您的整个模型,然后在您的 jquery post success 函数中将页面上的所有输入设置为返回的当前值. $('#Str').val(view.Str);并对页面上的任何其他模型数据执行相同操作。 +1 - “序列化所做的所有事情就是将表单中的输入编码为字符串,如果所有内容命名正确,aps.net 会将其绑定回您的模型。”感谢您的解释以及示例。【参考方案2】:

您可以更新视图,但不能更新模型。剃刀页面中的模型在服务器上编译以呈现视图;您需要在每次 ajax 请求后重新编译剃须刀页面。

唯一真正的选择是从服务器返回 json 并手动更新 DOM/View。

【讨论】:

以上是关于通过 Ajax Post 使用模型更改更新视图 - MVC3的主要内容,如果未能解决你的问题,请参考以下文章

如何通过调用ajax post保存数据时显示模型状态错误

POST 操作后视图不显示更新的数据

Vue.js 可排序列表 - 通过 AJAX 更新模型并保存更改位置

通过 AJAX 更新单选按钮更改的表单值

在 ruby​​ rails html 视图中使用 Ajax 表单更改图标“like”按钮类

ajax发布后淘汰js更新视图模型