如何使用jQuery更新ASP.NET MVC视图中绑定的Model数据
核心前提说明
Razor的@Model是服务器端渲染阶段的对象,当页面完成渲染发送到客户端之后,浏览器端不存在这个服务端Model实例,没法直接在JS里修改服务端的@Model。要复用服务端的计算逻辑,我们可以通过服务端渲染片段的方式实现,不用把计算逻辑写到前端JS里。
先修复现有代码的明显错误
- 视图里按钮ID拼接错误,原代码
id="btnSave-" + @invoice_Details.ID_Invoice_Details需要改成id="btnSave-@invoice_Details.ID_Invoice_Details" - JS里的输入框选择器缺少ID标识符,
$('Sale_Price-' + ID_Number)需要改成$('#Sale_Price-' + ID_Number) - AJAX配置混用了GET方法和POST参数,建议统一改为
$.ajax配置
最优实现方案:服务端返回渲染好的行片段
所有计算逻辑都放在服务端用Model实现,前端只做替换操作,完全不用写JS计算逻辑。
第一步:新增分部视图_InvoiceDetailRow.cshtml
把原来循环里的单行代码抽成独立分部视图,模型为单个Table.Invoice_Details,行合计逻辑直接在视图里用Model计算:
@model Table.Invoice_Details <tr id="row-@Model.ID_Invoice_Details"> <td> @Html.TextBoxFor(m => m.ID_Invoice_Details, new { id = "ID_Invoice_Details-" + Model.ID_Invoice_Details }) </td> <td> @Html.TextBoxFor(m => m.Sale_Price, new { id = "Sale_Price-" + Model.ID_Invoice_Details }) </td> <!-- 行合计直接在服务端计算,不需要前端参与 --> <td id="total-@Model.ID_Invoice_Details"> @(Model.Quantity * Model.Sale_Price) </td> <td> <button id="btnSave-@Model.ID_Invoice_Details">save</button> </td> </tr>
第二步:修改主视图的循环逻辑
直接调用分部视图渲染每一行:
@model List<Table.Invoice_Details> <table> @foreach (var invoice_Details in Model) { @await Html.PartialAsync("_InvoiceDetailRow", invoice_Details) } </table>
第三步:修改控制器SaveInvoice方法
保存成功后返回渲染好的单行片段,而非Json:
private Table.Smart_PosEntities Cn = new Table.Smart_PosEntities(); public IActionResult SaveInvoice(int ID_Invoice_Details, int Sale_Price) { Table.Invoice_Details invoice_Details = Cn.Invoice_Details.FirstOrDefault(L => L.ID_Invoice_Details == ID_Invoice_Details); if(invoice_Details == null) return NotFound(); invoice_Details.Sale_Price = Sale_Price; Cn.SaveChanges(); // 返回渲染完成的单行内容 return PartialView("_InvoiceDetailRow", invoice_Details); }
第四步:修改AJAX的success逻辑
直接替换对应行即可,服务端已经完成所有计算:
<script> $('button[id*=btnSave-]').click(function () { var FullID = $(this).attr('id'); var ID_Number = FullID.substring(FullID.indexOf('-') + 1); var Sale_Price = $('#Sale_Price-' + ID_Number).val(); $.ajax({ url: '/Invoice/SaveInvoice', type: 'post', data: { ID_Invoice_Details: ID_Number, Sale_Price: Sale_Price }, success: function (htmlResult) { // 直接替换整行,所有计算结果已经由服务端渲染完成 $('#row-' + ID_Number).replaceWith(htmlResult); } }) }) </script>
轻量备选方案:Json返回计算结果
如果不想引入分部视图,可以把服务端计算好的合计值放在Json里返回,前端直接赋值即可,计算逻辑依然保留在服务端:
- 控制器修改返回值:
return Json(new { ID_Invoice_Details = ID_Invoice_Details, Sale_Price = Sale_Price, // 服务端完成计算后返回 RowTotal = invoice_Details.Quantity * Sale_Price }, JsonRequestBehavior.AllowGet);
- JS success逻辑:
success: function (result) { $('#total-' + result.ID_Invoice_Details).text(result.RowTotal); }
内容的提问来源于stack exchange,提问作者ebrahem b
相关产品推荐
相关产品推荐

