2011-08-04 87 views
21

我需要从Ajax调用更新多个,我很困惑,因为在如何从Controller Action方法返回这些多个视图。从单个控制器操作返回多个部分视图?

+0

你想达到什么目的? –

+0

我有一个包含两个部分视图的页面,其中一个显示图表,另一个显示在图表中的项目列表在两个不同的部分视图中显示。现在对于不同的分组,这两个值都会改变,一个明显的解决办法可能是使它们成为我想要避免的单个局部视图。独立地,他们可以在我的应用程序中更频繁地使用。 – Nikshep

+0

你为什么不简单地做两个Ajax调用? – frennky

回答

42

您只能从函数中返回一个值,所以不能从一个操作方法返回多个部分。
如果您试图将两个模型返回到一个视图,请创建一个包含要发送的两个模型的视图模型,并将视图的模型设置为新的ViewModel。 例如

您的视图模型会是什么样子:

public class ChartAndListViewModel 
{ 
    public List<ChartItem> ChartItems {get; set;}; 
    public List<ListItem> ListItems {get; set;}; 
} 

那么你的控制器动作将是:

public ActionResult ChartList() 
{ 
    var model = new ChartAndListViewModel(); 
    model.ChartItems = _db.getChartItems(); 
    model.ListItems = _db.getListItems(); 

    return View(model); 
} 

最后你的看法是:

@model Application.ViewModels.ChartAndListViewModel 

<h2>Blah</h2> 

@Html.RenderPartial("ChartPartialName", model.ChartItems); 

@Html.RenderPartial("ListPartialName", model.ListItems); 
14

这里有一个很好的例子....
http://rhamesconsulting.com/2014/10/27/mvc-updating-multiple-partial-views-from-a-single-ajax-action/

创建的helper方法包装起来的局部视图...

public static string RenderRazorViewToString(ControllerContext controllerContext, 
    string viewName, object model) 
{ 
    controllerContext.Controller.ViewData.Model = model; 

    using (var stringWriter = new StringWriter()) 
    { 
     var viewResult = ViewEngines.Engines.FindPartialView(controllerContext, viewName); 
     var viewContext = new ViewContext(controllerContext, viewResult.View, controllerContext.Controller.ViewData, controllerContext.Controller.TempData, stringWriter); 
     viewResult.View.Render(viewContext, stringWriter); 
     viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View); 
     return stringWriter.GetStringBuilder().ToString(); 
    } 
} 

创建一个控制器动作捆绑多个部分视图....

[HttpPost] 
public JsonResult GetResults(int someExampleInput) 
{ 
    MyResultsModel model = CalculateOutputData(someExampleInput); 

    var totalValuesPartialView = RenderRazorViewToString(this.ControllerContext, "_TotalValues", model.TotalValuesModel); 
    var summaryValuesPartialView = RenderRazorViewToString(this.ControllerContext, "_SummaryValues", model.SummaryValuesModel); 

    return Json(new { totalValuesPartialView, summaryValuesPartialView }); 
} 

每个局部视图可以使用它的ow n模型(如果需要),或者可以与本例中的相同模型捆绑在一起。

然后,使用一个AJAX调用更新所有章节一气呵成:

$('#getResults').on('click', function() { 

    $.ajax({ 
     type: 'POST', 
     url: "/MyController/GetResults", 
     dataType: 'json', 
     data: { 
      someExampleInput: 10 
     }, 
     success: function (result) { 
      if (result != null) { 
       $("#totalValuesPartialView").html(result.totalValuesPartialView); 
       $("#summaryValuesPartialView").html(result.summaryValuesPartialView); 
      } else { 
       alert('Error getting data.'); 
      } 
     }, 
     error: function() { 
      alert('Error getting data.'); 
     } 
    }); 
}); 

如果你想用这个方法的GET请求,你需要删除[HttpPost]装饰和添加JsonRequestBehavior.AllowGet到返回JsonResult

return Json(new { totalValuesPartialView, summaryValuesPartialView }, JsonRequestBehavior.AllowGet); 
+0

非常优雅的解决方案,非常感谢。 – markau

+0

我喜欢这个解决方案,因为它允许你返回页面上同一位置不存在的多个局部视图。 – kerl

相关问题