Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How "separated" should views be?

I understand that a view should only display stuff and do no logic itself outside of what is required to display information.

What is the best way, in keeping that in mind, to handle this kind of simple scenario:

  1. User clicks Delete Item
  2. If the item is still associated with others, show "you can't delete this."
  3. Else, show a confirm form that posts to action /Delete/Id

I could very easily in the view do something like:

@if (Model.Children.Count > 0)
{
  <p>
    You can't delete this!
  </p>
}
else
{
  using (Html.BeginForm())
  {
    <p>
        Are you really sure you want to delete this?
    </p>
    <p>
        <input type="submit" value="Confirm" /> |
        @Html.ActionLink("Cancel", "Index")
    </p>
  }
}

Is there a compelling reason to make TWO Views and have the controller return the appropriate view depending on how many children there are? Seems like a tradeoff of simplicity and separation of concerns.

like image 571
Stevoman Avatar asked Oct 28 '11 16:10

Stevoman


3 Answers

It's a pretty simple example, so at first glance it appears harmless (and if it stays that way it certainly is). However, keep these factors in mind:

  • What if it becomes more than just children? Maybe three other relationships appear over time, and now you need to check for all of them in your view? Suddenly the code smell is a lot stronger.
  • Putting this type of logic in the controller may make other approaches to the problem more obvious or easy later, e.g., adding an ajax version that lets you give the user the "you can't delete this" feedback without leaving the previous page.
like image 134
super_seabass Avatar answered Nov 15 '22 08:11

super_seabass


I would separate those in 2 different views and have the controller action pick the correct view based on the view model value (Children.Count in this case). But this being said the other approach is not wrong neither. It works fine for simple scenarios like this.

like image 25
Darin Dimitrov Avatar answered Nov 15 '22 08:11

Darin Dimitrov


For this kind of a scenario typically you would have a Model property that actually was the flag of whether you can delete it or not (this is more in line with a ViewModel approach) so that the view isn't actually doing the logic, the controller is just telling the view what action is available.

@if(Model.CanDelete) {
    using (Html.BeginForm())
    {
        <p>
        Are you really sure you want to delete this?
        </p>
        <p>
            <input type="submit" value="Confirm" /> |
            @Html.ActionLink("Cancel", "Index")
        </p>
    }
} else {
    <p>You can't delete this!</p>
}

CanDelete can be filled in the controller using a combination of child data state, role membership, business status, etc. but to the view all of that stuff shouldn't matter

like image 38
Paul Tyng Avatar answered Nov 15 '22 08:11

Paul Tyng