开发者

Should I have different models and views for no user data than for some user data?

I'm just starting to learn asp.net mvc and I'm not sure what the right thing to do is.

I have a user and a user has a collection of (0 or more) reminders. I have a controller for the user which gets the reminders for the currently logged in user from a reminder service. It populates a model which holds some information about the user and the collection of reminders.

My question is should I have 2 different views, one for when there are no reminders and one for when there are some reminders? Or should I have 1 view which checks the number of reminders and displays different things? Having one view seems wrong as then I end up with code in my view which says if (Model.Reminders.Count==0){//do something} else {do something else}, and having logic in the view feels wrong. But if I want to have 2 different views then I'd like to have some code like this in my controller:

[Authorize]
p开发者_如何学Pythonublic ActionResult Index()
{
    MembershipUser currentUser = m_membershipService.GetUser();
    IList<Reminder> reminders = m_reminderRepository.GetReminders(currentUser);
    if (reminders.Count == 0)
    {
        var model = new EmptyReminderModel
        {
            Email = currentUser.Email,
            UserName = currentUser.UserName
        };
        return View(model);
    }
    else
    {
        var model = new ReminderModel
                       {
                           Email = currentUser.Email,
                           UserName = currentUser.UserName,
                           Reminders = reminders
                        };
        return View(model);
    }

but obviously this doesn't compile as the View can't take both different types. So if I'm going to do this should I return a specific named view from my controller, depending on the emptiness of the reminders, or should my Index() method redirect to other actions like so:

[Authorize]
public ActionResult Index()
{
    MembershipUser currentUser = m_membershipService.GetUser();
    IList<Reminder> reminders = m_reminderRepository.GetReminders(currentUser);
    if (reminders.Count == 0)
    {
        return RedirectToAction("ShowEmptyReminders");
    }
    else
    {
        return RedirectToAction("ShowReminders");
    }            
}

which seems nicer but then I need to re-query the reminders for the current user in the ShowReminders action.

Or should I be doing something else entirely?


For minor complexity like that, I don't find a problem with just having an '<% if.. else %>' block in the view. However, if you feel like really going the distance...

One potential answer would be to use DisplayTemplates. If you have one base UserBaseViewModel, and then your UserWithRemindersViewModel and UserWithoutRemindersViewModel inherit from UserBaseViewModel, then you can pass the UserBaseViewModel as the Generic type for your view, aka System.Web.Mvc.ViewPage<UserBaseViewModel>.

Then, depending your logic in the controller, you pass back a UserWithRemindersViewModel or the other to the view. (aka. return View(new UserWithoutRemindersViewModel()); // Inherits UserBaseViewModel, so everything is ok! )

Then, you can simply invoke the Html.DisplayFor(m => m) on your view.

If you make two templates in the \Views\<ControllerName>\DisplayTemplates\, UserWithRemindersViewModel.ascx, and UserWithoutRemindersViewModel.ascx. MVC will select the right display template for the type of your model you passed down, and since each of those PartialViews would be strongly typed to the right view model type, there is no need to <% if ... else %> to display the right HTML.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜