创建用于导航的ViewModel

时间:2013-11-25 03:48:04

标签: asp.net-mvc-4 navigation viewmodel partial-views

我有一个包含多个视图的MVC 4应用程序。即产品,食谱,Distrubutors&商店。

每个视图都基于模型。

让我们保持简单,并说我的所有控制器都传递类似的视图模型,看起来像我的产品操作:

public ActionResult Index()
{
    return View(db.Ingredients.ToList());
}

好的,这样很好,没问题。但是现在我的所有页面都工作了,我想改变我的导航(每个视图有下拉列表)来加载该模型中的项目。

所以我会有4个按钮(产品,食谱,分销商和商店)的导航。

当您翻转每个按钮时(假设我们滚动产品按钮),下拉列表会列出产品。

要做到这一点,我需要创建一些类型的ViewModel,它将所有4个模型组合在一起。显然,我不能只为每个导航元素剪切一个PartialView并使用

@model IEnumerable<GranSabanaUS.Models.Products>

然后为该下拉菜单重复产品,因为那时导航只能在产品视图中使用,而不能在其他任何地方使用。

(After the solution) AND YES ROWAN 您在我创建的导航类型中是正确的,请参阅此处: Navigation I am creating

2 个答案:

答案 0 :(得分:11)

简介

我将做一些假设,因为我没有所有的信息。

我怀疑你想要创造这样的东西:

Dropdown menu

分隔视图

当您遇到“如何将所有内容放入单个控制器/视图模型”的问题时,它可能会执行太多操作并需要进行分割。

不要将最后一页视为一个大视图 - 将视图划分为较小的视图,以便他们做“一件事”。

例如,导航只是布局的一部分。您可以更进一步地说每个下拉菜单都是导航的一部分,依此类推。

导航概述

假设您有_Layout.cshtml,如下所示:

<body>
    <div class="navbar">
        <ul class="nav">
            <li><a href="#">Products</a></li>
            <li><a href="#">Recipes</a></li>
        </ul>
    </div>

    @RenderBody()
</body>

如您所见,我们有一个简单的导航系统,然后渲染主体。我们面临的问题是:我们如何提取此导航并为其提供渲染所有内容所需的模型?

提取导航

让我们将导航提取到自己的视图中。抓取导航HTML并将其粘贴到名为__Navigation.cshtml_的新视图中,并将其放在~/Views/Partials下。

<强> _Navigation.cshtml

<div class="navbar">
    <ul class="nav">
        <li><a href="#">Products</a></li>
        <li><a href="#">Recipes</a></li>
    </ul>
</div>

创建一个名为 PartialsController 的新控制器。创建一个新动作来调用我们的导航。

<强> PartialsController.cs

[ChildActionOnly]
public class PartialsController : Controller
{
    public ActionResult Navigation()
    {
        return PartialView("_Navigation");
    }

}

更新我们的布局以调用导航。

<强> _Layout.cshtml

<body>
    @Html.Action("Navigation", "Partials")

    @RenderBody()
</body>

现在我们的导航被分成了自己的局部视图。它更加独立和模块化,现在可以更轻松地为其提供模型数据。

注入模型数据

假设我们有一些模型,例如您提到的模型。

public class Product { //... }
public class Recipe { //... }

让我们创建一个视图模型:

<强> NavigationViewModel.cs

public class NavigationViewModel
{
    public IEnumerable<Product> Products { get; set; }
    public IEnumerable<Recipe> Recipes { get; set; }
}

让我们来解决问题:

<强> PartialsController.cs

public ActionResult Navigation()
{
    NavigationViewModel viewModel;

    viewModel = new NavigationViewModel();
    viewModel.Products = db.Products;
    viewModel.Recipes = db.Recipes;

    return PartialView("_Navigation", viewModel);
}

最后,更新我们的观点:

<强> _Navigation.cshtml

@model NavigationViewModel

<div class="navbar">
    <ul class="nav">

        @foreach (Product product in Model.Products)
        {
            @<li>product.Name</li>
        }

        @foreach (Recipe recipe in Model.Recipes)
        {
            @<li>recipe.Name</li>
        }
    </ul>
</div>

答案 1 :(得分:1)

public class MenuContents
{
    public IEnumerable<Products> AllProducts { get; set; }
    public IEnumerable<Recepies> AllRecepies { get; set; }
    public IEnumerable<Distributors> AllDistributors { get; set; }
    public IEnumerable<Stores> AllStores { get; set; }

    private XXXDb db = new XXXUSDb();

    public void PopulateModel()
    {
        AllProducts = db.Products.ToList();
        AllRecepies = db.Recepies.ToList();
        AllDistributors = db.Distributors.ToList();
        AllStores = db.Stores.ToList();
    }
}

然后在您的控制器中

public ActionResult PartialWhatever()
{
    MenuContents model = new MenuContents();
    model.PopulateModel();

    return PartialView("PartialViewName", model);
}

然后在你的局部视图中

@Model MenuContents

... do whatever here