When do I use View Models, Partials, Templates and handle child bindings with MVC 3
Asked Answered
I

1

11

new to mvc3, i have a few questions, would appreciate if someone could answer/provide links:

  1. When should I use View Models? Is it not recommended to use the domain? I find that my view models are copies of my domain objects, and don't see the value...
  2. When should I use Partials? Is it only if the partial view will be reused?
  3. When should I use Display Templates and Editor Templates? Can I use these without a view model?
  4. How do I create an edit screen where the parent and list of child objects are both editable? i.e. a few fields at the top (parent) and a grid of fields below (like editable rows), particularly, how do i do the binding? automapper is not used.

Thanks!

Inspector answered 27/5, 2011 at 20:25 Comment(0)
G
23

When should I use View Models? Is it not recommended to use the domain? I find that my view models are copies of my domain objects, and don't see the value...

View models should always be used. You should not use your domain models in the view.

View models are not exact copies of the domain models. They always have some differences related to the specific requirements of the view. For example on one screen you would like to present some of the properties of your domain model and on other screen other properties. As a consequence to this you will also have different validation requirements as one property will be required on one screen and not required on other screen. So you will also have different data annotations on those view models.

When should I use Partials? Is it only if the partial view will be reused?

Not only if the view will be reused. Partials could be used to make your views more structured. Also if you are using AJAX, partials make it easier. You would send the AJAX request to a controller action which will return a partial view allowing you to update only portions of the DOM.

When should I use Display Templates and Editor Templates? Can I use these without a view model?

Always. You can use them with any strongly typed model, but you should always use a view models (see answer to previous question).

How do I create an edit screen where the parent and list of child objects are both editable? i.e. a few fields at the top (parent) and a grid of fields below (like editable rows), particularly, how do i do the binding? automapper is not used.

That's a pretty broad question but to answer it as always you start with defining your view models which will represent/contain the properties you would like to present on this screen for editing:

public class ChildViewModel
{
    [Required]
    public string Name { get; set; }
}

public class ParentViewModel
{
    [Required]
    public string Name { get; set; }

    public IEnumerable<ChildViewModel> Children { get; set; }
}

then a controller:

public class HomeController: Controller
{
    public ActionResult Index()
    {
        // TODO: Fetch an actual domain model from your repository,
        // and map it to the view model (AutoMapper is a great tool for the job)

        var model = new ParentViewModel
        {
            Name = "parent name",
            Children = Enumerable.Range(1, 5).Select(x => new ChildViewModel
            {
                Name = "child " + x
            })
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(ParentViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // TODO: the model object here will contain the new values
        // => user AutoMapper to map it back to a domain model
        // and pass this domain model to the repository for processing

        return RedirectToAction("Index");
    }
}

and finally the view:

@model ParentViewModel
@using (Html.BeginForm())
{
    <h2>Parent</h2>
    <div>
        @Html.LabelFor(x => x.Name)
        @Html.EditorFor(x => x.Name)
        @Html.ValidationMessageFor(x => x.Name)
    </div>

    <h2>Children</h2>
    <table>
        <thead>
            <tr>
                <th>Child name</th>
            </tr>
        </thead>
        <tbody>
            @Html.EditorFor(x => x.Children)
        </tbody>
    </table>
    <input type="submit" value="OK" />
}

and the last piece is the editor template for a child (~/Views/Home/EditorTemplates/ChildViewModel.cshtml):

@model ChildViewModel
<tr>
    <td>
        @Html.LabelFor(x => x.Name)
        @Html.EditorFor(x => x.Name)
        @Html.ValidationMessageFor(x => x.Name)
    </td>
</tr>
Gianna answered 28/5, 2011 at 9:1 Comment(6)
Thanks! Thats really helpful, just want to clarify a few points: 1. Is the modelbinding able to bind both parent and child automatically? 2. Do i need to create display and editor templates for EditorFor to work? Or is mvc clever enough to create them for me based on the view models? 3. Should a view model for an edit specific view contain everything needed for that view or only editable fields? Some fields may need to be readonly...Inspector
I had the same question about how you handle view models for Edit and Create. I have a situation where the edit has required fields that can't be populated during the create due to no exiting child data. Do you create two view models in that case?Rocray
@PilotBob, yes, two view models in this case.Gianna
@DarinDimitrov I guessed your name before hand by luking at the level of explanation. You r awesome !!!Synchrocyclotron
In your example you're breaking your own rule about always using editor templates (ParentViewModel could be rendered using an editor template). I would argue you should only use them when it will be reused in different views or, as you say, provides structure to your presentation code.Thermostatics
@Thermostatics Agree! If the whole view is the viewmodel on a non reusable view. Display/EditorTemplate has no sense. I guess that's why.Percheron

© 2022 - 2024 — McMap. All rights reserved.