如何从Ajax返回的PartialViewResult模型中获取ID并赋值给ActionLink
解决方案:从Ajax返回的PartialView模型提取ID并更新父视图ActionLink
我来帮你搞定这个问题!要从Ajax返回的PartialView模型里提取ID并更新父视图的ActionLink,这里有两种实用的方案,你可以根据自己的场景选择:
方案1:在PartialView中嵌入隐藏字段存储ID(最简单)
这个方案不需要修改控制器的返回类型,只需要在分部视图里加个隐藏字段存放你需要的ID,然后在Ajax成功回调里读取这个字段并更新ActionLink的URL。
步骤1:修改分部视图,添加隐藏字段
假设你的模型(比如MyModel)里有一个需要提取的ID属性(比如TargetId),在分部视图的开头或结尾添加隐藏字段:
@* 新增:隐藏字段存储目标ID *@ <input type="hidden" id="targetContactId" value="@Model.TargetId" /> @foreach (var item in Model.drr) { <tr> <td>@Html.DisplayFor(modelItem => item.DateRange1)</td> </tr> }
如果ID是集合中某个特定项的属性(比如第一个项的ID),可以改成:
<input type="hidden" id="targetContactId" value="@Model.drr.FirstOrDefault()?.Id" />
步骤2:给父视图的ActionLink添加ID,方便JS定位
修改父视图的ActionLink,加上id属性:
@Html.ActionLink("Redirect", "Action", new { SingleDatePicker = "" }, new { id = "redirectActionLink" })
步骤3:完善OnSuccess回调函数,更新ActionLink的URL
在父视图的JS函数里,从更新后的DOM中读取隐藏字段的值,然后修改ActionLink的href参数:
function OnAjaxRequestSuccess(data) { // 从更新后的DepartmentDetails容器里获取隐藏字段的ID值 var targetId = document.getElementById('targetContactId').value; // 获取要更新的ActionLink元素 var redirectLink = document.getElementById('redirectActionLink'); // 处理URL参数:替换或追加SingleDatePicker参数 var originalHref = redirectLink.href; var paramKey = "SingleDatePicker"; var newParam = `${paramKey}=${targetId}`; if (originalHref.includes(`${paramKey}=`)) { // 已有参数,替换它 redirectLink.href = originalHref.replace(new RegExp(`${paramKey}=[^&]*`), newParam); } else { // 没有参数,追加到URL末尾 redirectLink.href += originalHref.includes('?') ? `&${newParam}` : `?${newParam}`; } }
方案2:控制器返回JSON(包含HTML和ID),直接获取模型数据
如果不想依赖DOM隐藏字段,可以让控制器返回一个包含渲染好的PartialView HTML和目标ID的JSON对象,这样在回调里直接拿到ID,更可靠。
步骤1:添加PartialView转HTML的辅助方法
在控制器里添加一个辅助方法,把PartialView渲染成字符串:
protected string RenderPartialViewToString(string viewName, object model) { ViewData.Model = model; using (var stringWriter = new StringWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, stringWriter); viewResult.View.Render(viewContext, stringWriter); viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View); return stringWriter.GetStringBuilder().ToString(); } }
步骤2:修改控制器,返回JSON对象
把原来返回PartialViewResult改成返回包含HTML和ID的JSON:
public ActionResult GetContacts(string q, int limit = 5, int p = 1, int per_page = 5) { // 这里替换成你获取模型的逻辑(比如从数据库查询) var model = Model; return Json(new { Html = RenderPartialViewToString("DateRange2_Partial", model), TargetId = model.TargetId // 这里放你需要的ID属性 }, JsonRequestBehavior.AllowGet); }
步骤3:修改父视图的Ajax配置和回调函数
去掉UpdateTargetId和InsertionMode,自己在回调里更新DOM和ActionLink:
@Ajax.ActionLink("click me", "GetContacts", "Home", new AjaxOptions { HttpMethod = "GET", OnSuccess = "OnAjaxRequestSuccess" }) <script type="text/javascript"> function OnAjaxRequestSuccess(response) { // 1. 更新DepartmentDetails容器的HTML document.getElementById('DepartmentDetails').innerHTML = response.Html; // 2. 获取ID并更新ActionLink的URL var targetId = response.TargetId; var redirectLink = document.getElementById('redirectActionLink'); // 和方案1一样的URL参数处理逻辑 var originalHref = redirectLink.href; var paramKey = "SingleDatePicker"; var newParam = `${paramKey}=${targetId}`; if (originalHref.includes(`${paramKey}=`)) { redirectLink.href = originalHref.replace(new RegExp(`${paramKey}=[^&]*`), newParam); } else { redirectLink.href += originalHref.includes('?') ? `&${newParam}` : `?${newParam}`; } } </script> @Html.ActionLink("Redirect", "Action", new { SingleDatePicker = "" }, new { id = "redirectActionLink" })
为什么TempData没用?
TempData是跨请求存储数据,但父视图的ActionLink是在页面初始渲染时生成的静态HTML,Ajax请求是异步的,TempData无法直接修改已经渲染好的页面元素,必须通过JavaScript动态更新,这也是上面两个方案的核心思路。
内容的提问来源于stack exchange,提问作者PaTHP
相关产品推荐
相关产品推荐

