如何用jQuery一步加载ASP.NET MVC分部视图并获取模型数据
更优解决方案:避免两次HTTP请求,高效传递模型数据
咱先说说为啥你原来的方案不太理想——两次HTTP请求不仅增加了服务器压力,还会让页面加载变慢,用户体验打折扣。下面给你几个更优的方案,都能避免重复请求,代码也更简洁:
方案1:在分部视图中嵌入JSON格式的模型数据
直接把模型序列化成JSON,嵌入到分部视图的<script>标签或者DOM元素的data-*属性里,加载分部视图后就能直接读取数据,不用额外发请求。
步骤1:修改分部视图(Gallery.cshtml)
在视图末尾添加一段脚本,把模型转成全局变量:
<!-- 原分部视图内容 --> <script> // 将模型序列化为JSON,存到全局变量中 window.galleryImages = @Html.Raw(Json.Serialize(Model)); </script>
或者也可以把数据存在DOM元素的data属性里(更符合模块化原则):
<div id="galleryContainer" data-images='@Html.Raw(Json.Serialize(Model))'> <!-- 原分部视图内容 --> </div>
步骤2:简化jQuery代码
去掉多余的$.get请求,直接在load回调里读取嵌入的数据:
function displayGallery(folder) { $("#partialView").load("/gallery/getview", { folder: folder }, function () { // 从全局变量读取数据(对应第一种嵌入方式) // let images = window.galleryImages; // 或者从DOM data属性读取(对应第二种嵌入方式) let images = $("#galleryContainer").data("images"); let tbl_body = ""; $.each(images, function () { let tbl_row = ""; $.each(this, function (k, v) { // 注意这里修正了字符串拼接的引号问题,避免语法错误 tbl_row += `<td class="mytd" colspan='1'> <div> <img class="myimg" src="${v}"> <br/> <p style="text-align:center;">${k}</p> </div> </td>`; }); tbl_body += `<tr>${tbl_row}</tr>`; }); $("#mytbody").append(tbl_body); console.log("视图加载和数据渲染完成"); }); console.log("displayGallery function " + folder); }
方案2:让Action同时返回视图HTML和模型数据
如果需要把视图HTML和模型数据分开处理,可以让GetView Action返回一个包含两者的JSON对象,前端一次请求就能拿到所有需要的内容。
步骤1:修改控制器Action
先实现一个辅助方法,把分部视图转成字符串,再返回包含HTML和数据的JSON:
public class GalleryController : Controller { // 辅助方法:将分部视图转为字符串 private string PartialViewToString(string viewName, object model) { ViewData.Model = model; using (var sw = new StringWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View); return sw.GetStringBuilder().ToString(); } } public IActionResult GetView(string folder) { List<Image> Images = new List<Image>(); Image image = new Image(); image.ImageName = "myname"; image.ImageUri = "myuri"; Images.Add(image); // 生成分部视图HTML string viewHtml = PartialViewToString("Gallery", Images); // 返回包含HTML和模型数据的JSON return Json(new { Html = viewHtml, Data = Images }); } }
注:如果是ASP.NET Core,辅助方法的写法会略有不同,需要注入
ICompositeViewEngine和ITempDataProvider来实现视图转字符串。
步骤2:修改jQuery代码
用$.get代替load,一次请求拿到所有内容后,先渲染视图再处理数据:
function displayGallery(folder) { $.get("/gallery/getview", { folder: folder }, function (response) { // 先渲染分部视图HTML $("#partialView").html(response.Html); // 再用返回的模型数据生成表格 let tbl_body = ""; let data = response.Data; $.each(data, function () { let tbl_row = ""; $.each(this, function (k, v) { tbl_row += `<td class="mytd" colspan='1'> <div> <img class="myimg" src="${v}"> <br/> <p style="text-align:center;">${k}</p> </div> </td>`; }); tbl_body += `<tr>${tbl_row}</tr>`; }); $("#mytbody").append(tbl_body); console.log("视图加载和数据渲染完成"); }); console.log("displayGallery function " + folder); }
方案对比
- 方案1:最简洁高效,只需要一次请求,代码改动最少,推荐优先使用。
- 方案2:适合需要将视图渲染和数据处理完全分离的场景,但需要额外编写视图转字符串的辅助方法。
这两个方案都能避免你原来的两次请求问题,同时保持代码的可读性和可维护性。
内容的提问来源于stack exchange,提问作者Jeremy Parker
相关产品推荐
相关产品推荐

