Create ViewModel for Navigation

前端 未结 2 648
太阳男子
太阳男子 2021-01-03 09:50

I have an MVC 4 application with several views. I.e. Products, Recipes, Distrubutors & Stores.

Each view is based around a model.

Let\'s keep it simple

相关标签:
2条回答
  • 2021-01-03 10:35
    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();
        }
    }
    

    Then in your controller

    public ActionResult PartialWhatever()
    {
        MenuContents model = new MenuContents();
        model.PopulateModel();
    
        return PartialView("PartialViewName", model);
    }
    

    Then in your partial view

    @Model MenuContents
    
    ... do whatever here
    
    0 讨论(0)
  • 2021-01-03 10:45

    Introduction

    I'm going to be making a few assumptions because I don't have all the information.

    I suspect you want to create something like this:

    Dropdown menu

    Separating views

    When you run into the issue of "How do I put everything into a single controller/viewmodel" it's possible that it's doing too much and needs to be divided up.

    Don't treat your a final page as one big view - divide the views up into smaller views so they are doing 'one thing'.

    For example, the navigation is just one part of your layout. You could go even further to say that each dropdown menu is a single view that are part of the navigation, and so on.

    Navigation overview

    Suppose you have a _Layout.cshtml that looks like this:

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

    As you can see we have a simple navigation system and then the main body is rendered. The problem that we face is: How do we extract this navigation out and give it the models it needs to render everything?

    Extracting the navigation

    Let's extract the navigation into it's own view. Grab the navigation HTML and paste it into a new view called __Navigation.cshtml_ and put it under ~/Views/Partials.

    _Navigation.cshtml

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

    Create a new controller called PartialsController. Create a new action to call our navigation.

    PartialsController.cs

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

    Update our Layout to call the navigation.

    _Layout.cshtml

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

    Now our navigation is separated out into its own partial view. It's more independent and modular and now it's much easier to give it model data to work with.

    Injecting model data

    Suppose we have a few models such as the ones you mentioned.

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

    Let's create a view-model:

    NavigationViewModel.cs

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

    Let's fix up our action:

    PartialsController.cs

    public ActionResult Navigation()
    {
        NavigationViewModel viewModel;
    
        viewModel = new NavigationViewModel();
        viewModel.Products = db.Products;
        viewModel.Recipes = db.Recipes;
    
        return PartialView("_Navigation", viewModel);
    }
    

    Finally, update our view:

    _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>
    
    0 讨论(0)
提交回复
热议问题