通过 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 输入放在 <form>
中,这样您就可以让 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的主要内容,如果未能解决你的问题,请参考以下文章
Vue.js 可排序列表 - 通过 AJAX 更新模型并保存更改位置