1

我有一个局部视图,@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! 看起来你正在调用一个正常的方法!

4

1 回答 1

0

我认为您可以使用@Html.RenderAction而不是 RenderPage。然后你可以设计一个动作,传递参数并选择你的局部视图。

有一个很好的博客here关于这个。

于 2012-12-19T15:53:13.673 回答