如何在AJAX成功回调中区分并显示条件返回的局部视图
如何在AJAX Success回调中区分不同的局部视图
我来分享几个实用的方案,帮你在AJAX的success回调里准确识别Controller返回的不同局部视图:
方案1:返回包含标识的JSON对象
这种方式最直观,Controller把局部视图转成HTML字符串后,和视图标识一起打包成JSON返回给前端。
首先,你需要在Controller里加一个辅助方法,把局部视图渲染成字符串:
private string RenderViewToString(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(); } }
然后在Action里根据条件返回JSON:
public ActionResult MyAction() { if (conditionA) { var model = GetModelA(); return Json(new { ViewType = "ViewA", HtmlContent = RenderViewToString("_ViewA", model) }, JsonRequestBehavior.AllowGet); } else if (conditionB) { var model = GetModelB(); return Json(new { ViewType = "ViewB", HtmlContent = RenderViewToString("_ViewB", model) }, JsonRequestBehavior.AllowGet); } // 默认返回 return Json(new { ViewType = "DefaultView", HtmlContent = RenderViewToString("_DefaultView", null) }, JsonRequestBehavior.AllowGet); }
最后在AJAX的success回调里判断标识并渲染:
var success = function(response) { // 根据ViewType判断是哪个视图 switch(response.ViewType) { case "ViewA": // 展示ViewA的内容 $("#targetContainer").html(response.HtmlContent); break; case "ViewB": // 展示ViewB的内容,还可以做额外逻辑 $("#targetContainer").html(response.HtmlContent); alert("加载了ViewB"); break; default: $("#targetContainer").html(response.HtmlContent); } };
方案2:在局部视图中嵌入标识元素
如果不想改Controller的返回格式(直接返回PartialView),可以在每个局部视图里加一个隐藏的标识元素,前端解析HTML的时候读取这个标识。
比如在_ViewA.cshtml里加:
<input type="hidden" class="view-identifier" value="ViewA"> <!-- 视图其他内容 --> <div>这是ViewA的内容</div>
在_ViewB.cshtml里加:
<input type="hidden" class="view-identifier" value="ViewB"> <!-- 视图其他内容 --> <div>这是ViewB的内容</div>
然后Controller直接返回PartialView:
public ActionResult MyAction() { if (conditionA) { var model = GetModelA(); return PartialView("_ViewA", model); } else if (conditionB) { var model = GetModelB(); return PartialView("_ViewB", model); } return PartialView("_DefaultView"); }
AJAX的success回调里这样处理:
var success = function(response) { // 把返回的HTML转成DOM对象 var tempElement = $("<div>").html(response); // 获取标识值 var viewType = tempElement.find(".view-identifier").val(); switch(viewType) { case "ViewA": $("#targetContainer").html(tempElement); // 做ViewA专属的逻辑,比如绑定事件 $("#targetContainer .viewA-btn").click(function() { /*...*/ }); break; case "ViewB": $("#targetContainer").html(tempElement); // ViewB的专属逻辑 break; default: $("#targetContainer").html(tempElement); } };
方案3:利用HTTP响应头传递标识
这种方式不需要修改视图内容,也不用返回JSON,而是在Controller里给响应头加一个自定义字段,前端通过AJAX的xhr对象读取这个字段。
Controller代码:
public ActionResult MyAction() { if (conditionA) { Response.Headers.Add("X-View-Identifier", "ViewA"); var model = GetModelA(); return PartialView("_ViewA", model); } else if (conditionB) { Response.Headers.Add("X-View-Identifier", "ViewB"); var model = GetModelB(); return PartialView("_ViewB", model); } Response.Headers.Add("X-View-Identifier", "DefaultView"); return PartialView("_DefaultView"); }
AJAX的success回调需要获取xhr对象(注意:jQuery的AJAX里可以通过success的第三个参数拿到xhr):
// 注意这里要加上xhr参数 var success = function(response, status, xhr) { var viewType = xhr.getResponseHeader("X-View-Identifier"); if (viewType === "ViewA") { $("#targetContainer").html(response); // ViewA的额外逻辑 } else if (viewType === "ViewB") { $("#targetContainer").html(response); // ViewB的额外逻辑 } else { $("#targetContainer").html(response); } };
这三个方案各有优劣:
- 方案1最灵活,能同时传递其他数据,但需要额外写视图转字符串的方法;
- 方案2对Controller侵入最小,但需要修改每个局部视图;
- 方案3干净利落,不影响视图和返回格式,但要注意跨域场景下响应头的暴露问题(如果是同域就没问题)。
你可以根据自己的项目情况选最适合的~
内容的提问来源于stack exchange,提问作者Muhammad Asif
相关产品推荐
相关产品推荐

