如何填充MVC Razor部分视图

29

我需要创建一个视图,显示订单头信息,并且需要添加一个显示行项目网格的部分视图。该部分视图将从视图模型强类型化。我知道应该使用HTML助手@Html.Partial("Path/view")。到目前为止,我只使用控制器打开视图,在将其发送到视图之前填充视图模型。因为部分视图是从html助手调用的,所以我想知道用模型数据填充部分视图的最佳方法是什么。

2个回答

53

选项1:继承父页面

默认情况下,通过调用 @Html.Partial("PartialViewName") 渲染的任何局部视图都将获得传递给父视图的视图模型。

所以,如果您有:

视图模型

namespace MyNamesapce
{
    public OrderInfoViewModel
    {
        public string OrderTitle { get; set; }
        public IEnumerable<OrderItem> OrderItems { get; set; }
    }
}

订单信息.cshtml

@model MyNamespace.OrderInfoViewModel

<h1>@Model.OrderTitle</h1>

@Html.Partial("OrderLineItems")

OrderLineItems页面应该传递一个MyNamespace.OrderViewModel,因此您的部分视图应如下所示:

OrderLineItems.cshtml

@model MyNamespace.OrderInfoViewModel

foreach (var orderItem in Model.OrderItems)
{
    //Do stuff
}

选项2: 指定模型

您可以使用第二个参数来指定要传递的视图模型。例如:

OrderInfo.cshtml

@model MyNamespace.OrderInfoViewModel

<h1>@Model.OrderTitle</h1>

@Html.Partial("OrderLineItems", Model.OrderItems)

订单行项目.cshtml

@model IEnumerable<OrderItem>

foreach (var orderItem in Model)
{
    //Do stuff
}

选项三:使用部分操作

如果您需要在多个页面上重复使用一个局部视图,那么使用部分视图可能是一个不错的选择,可以避免因为页面使用相同的部分而必须填充不同的视图模型相同信息的情况。

例如:

视图模型

namespace MyNamesapce
{
    public OrderInfoViewModel
    {
        public string OrderTitle { get; set; }
    }
}

控制器

public class OrderController : Controller
{
    public ActionResult OrderInfo(int orderId)
    {
        OrderInfoViewModel viewModel = GetViewModel(orderId);
        return View(viewModel);
    }

    public PartialViewResult OrderLineItems(int orderId)
    {
        IEnumerable<OrderItem> orderItems = GetOrderItems(orderId);
        return Partial(orderItems);
    }
}

订单信息.cshtml

@model MyNamespace.OrderInfoViewModel

<h1>@Model.OrderTitle</h1>

@Html.Action("OrderLineItems")

订单行项目.cshtml

@model IEnumerable<OrderItem>

foreach (var orderItem in Model.OrderItems)
{
    //Do stuff
}

在什么情况下,选项3比2更受欢迎?我难道不能重复调用部分视图并仍然保持DRY吗? - NickSuperb
使用选项1和2,您必须将主页面视图模型填充为部分视图所需的所有数据。在这个问题/答案的情况下并不是最好的,所以假设您有一个购物车摘要小部件,它显示在许多页面上...使用选项#3会更容易。否则,每个还显示购物车小部件(大多数页面)的操作都需要负责将其视图模型填充为购物车小部件所需的数据。 - Charlino
我现在意识到,你必须间接地而不是直接地将模型持续地注入到部分视图中。 - NickSuperb
1
我认为选项3看起来适合我的情况。我将为所有订单使用相同的标题,但根据订单在流程中的位置,使用三个不同的行项目部分视图之一。似乎在控制器中动态分配部分视图是最好的地方。 - Alan Fisher

6

使用部分视图时,您只需像正常视图一样发送一个模型。例如,如果您的模型有一个名为“LineItems”的LineItem对象属性,则可以执行以下操作:

@Html.Partial("_PartialName", Model.LineItems)

如果您的模型没有该属性,您可以添加它,或者以其他方式传递它,例如ViewBag(我更喜欢强类型方法,但这是我的观点):

@Html.Partial("_PartialName", (List<LineItem>)ViewBag.LineItems)

这些不是唯一的方法,但它们是我首选的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接