我有一个局部视图,@RenderPage 和控制器的操作都将调用它。
下面是使用 @RenderPage 从另一个视图调用它的代码,它使用 PageData[] 传递参数:
@foreach (var subTree in itemTree.SubTrees)
{
<li id ="@("LiOf" + subTree.Root.ID)" style = "margin-top: 0px">
@RenderPage("~/Areas/MFC/Views/Items/_SubItemsTree.cshtml", subTree, itemTreeViewModel, false, Request.RawUrl, showOpenAsTreeRoot)
</li>
}
顺便说一句,这个局部视图是一个“treeNode”,因此它会通过一次调用多次呈现。
下面是一个控制器的action中的代码,它通过Model和ViewBag传递参数,当某个节点需要刷新时,这个action会被调用:
var fatherTree = ItemTree.ItemTreeOf(item.FatherID);
ViewBag.IsSubtreeRoot = true;
ViewBag.ReturnUrl = returnUrl;
ViewBag.ItemTreeViewModel = new ItemTreeViewModel(
view, fatherTree, whats, types,
showPopupOperationMenu: true, showMoveLeftRight: true, showMoveUpDown: true);
ViewBag.ShowOpenAsTreeRoot = true;
return View("~/Areas/MFC/Views/Items/_SubItemsTree.cshtml", fatherTree);
要在这两种情况下正常工作,要渲染的视图是这样的:
@model ItemTree
@using Martian.Areas.MFC.Models;
@{
var itemTree = (PageData[0] as ItemTree) ?? Model;
var itemTreeViewModel = PageData[1] ?? ViewBag.ItemTreeViewModel as ItemTreeViewModel;
var isSubtreeRoot = (bool) (PageData[2] ?? ViewBag.IsSubtreeRoot);
var returnUrl = PageData[3] ?? ViewBag.ReturnUrl as string;
var showOpenAsTreeRoot = (bool)(PageData[4] ?? ViewBag.ShowOpenAsTreeRoot);
是的,它运作良好但看起来很尴尬。由于我有一组局部视图需要被转移以由@RenderPage 而不是@Html.RenderPartial 调用,并且它们也需要通过某些操作返回,这将是一个问题。有没有更好的方法来做到这一点?谢谢。
2013-01-19 一个痛苦但可行的解决方案在这里:
大脑的训练是:如果我们可以将多个参数传递给Controller.View,我们可以将它作为PageData[]传递给cshtml。
步骤 1. 修改来自控制器的调用:
public ActionResult AjaxRemoveUser(int departmentID, int teamID, string userName, int udcTypeValue)
{
var team = _repMFC.ReadItemAt<Department>(teamID);
team.RemoveUser(udcTypeValue, userName);
return MFCView("AssignMembers/_AjaxTeam", _repMFC.ReadItemAt<Department>(departmentID), team, true);
}
步骤 2. 从 MFCController 而不是控制器和 . MFCController 是我们之前出于某种原因设计的类,我们所有的控制器都是从它派生的。
在 MFCController 中,有 MFCView() 的主体,如下所示:
public ActionResult MFCView(string ajaxViewName, params object[] list)
{
var ajaxViewPath = ((BuildManagerCompiledView) (ViewEngines.Engines.FindPartialView(ControllerContext, ajaxViewName).View)).ViewPath;
var viewModel = new MFCViewModel { AjaxViewPath = ajaxViewPath, PageData = list };
return View("~/Views/Shared/_MFCView.cshtml", viewModel);
}
步骤 3. MFCViewModel:
public class MFCViewModel
{
public string AjaxViewPath;
public object[] PageData;
}
这是非常清晰和直截了当的。
第 4 步。~/Views/Shared/_MFCView.cshtml
@model Martian.Areas.MFC.Models.MFCController.MFCViewModel
@{
@RenderPage(Model.AjaxViewPath, Model.PageData)
}
第 5 步。在视图 AssignMembers/_AjaxTeam.cshtml 中:正如我在主题一开始所描述的,它曾经看起来像:
var department = (PageData[0]??ViewBag.Department) as Department;
var team = (PageData[1]??ViewBag.Team) as Department;
var enableEditMembers = (bool)(PageData[2]??ViewBag.EnableEditMembers);
现在它实际上是:
var department = PageData[0] as Department;
var team = PageData[1] as Department;
var enableEditMembers = (bool) PageData[2];
现在,PageData 由我们传递给 MFCView() 的参数创建。
虽然这个过程看起来很痛苦,但是一旦你完成了工作,你可以使用 MFCView 传递你想要的任意数量的参数,没有 ViewBag,没有 ViewData[],甚至没有 ViewModel! 看起来你正在调用一个正常的方法!