Is the sentence formatting I do here view logic or not?
I have a page containing a partial view with a list and a partial view with three filter options. If the list is empty, I show a special partial view instead of the list with some tips for the user. The tip will instruct the user to widen the filter options that are not already set to it's most generic form. I could just present a bulleted list of all the options the user could change, doing something like this (LocalizedText is generated from a resource file):
<%@ Import Namespace="Resources" %>
<%@ Import Namespace="System.Web.Mvc" %>
<%@ Import Namespace="MyProject.Models" %>
<%@ Control Language="C#" Inherits="ViewUserControl<EmptyResultViewModel>" %>
<div class="warning">
<ul>
<% if (!string.IsNullOrEmpty(Model.SelectedCustomerNumber)) %>
<% { %>
<li><%: LocalizedText.TipCustomerNumber %> </li>
<% } %>
<% if (Model.SelectedPeriodOption != PeriodOption.EntirePeriod) %>
<% { %>
<li><%: LocalizedText.TipPeriod %> </li>
<% } %>
<% if (Model.SelectedFilterOption != FilterOption.None) %>
<% { %>
<li><%: LocalizedText.TipFilter %> </li>
<% } %>
</ul>
</div>
I think this would be considered OK view logic. However, I want it to be one grammatically correct sentence. I now have four extra tip resources:"
Tip0 = "No results found";
Tip1 = "No results found, consider choosing {0}.";
Tip2 = "No results found, consider choosing {0} or {1}.";
Tip3 = "No results found, consider choosing {0}, {1} or {2}.";
TipCustomerNumber = "another customer number";
TipPeriod = "a different period";
TipFilter = "a more generic filter";
And my view becomes this:
<%@ Import Namespace="Resources" %>
<%@ Import Namespace="System.Web.Mvc" %>
<%@ Import Namespace="MyProject.Models" %>
<%@ Control Language="C#" Inherits="ViewUserControl<EmptyResultViewModel>" %>
<% var tips = new List<string>();
// Add the tips of the filter items that are not set to the most general search criteria to a list.
if (!string.IsNullOrEmpty(Model.SelectedCustomerNumber))
{
tips.Add(LocalizedText.TipCustomerNumber);
}
if (Model.SelectedPeriodOption != PeriodOption.EntirePeriod)
{
tips.Add(LocalizedText.TipPeriod);
}
if (Model.SelectedFilterOption != FilterOption.None)
{
tips.Add(LocalizedText.TipFilter);
}
// Depending on how many tips there are, choose the correct tip format.
string message;
switch (tips.Count)
{
case 0:
message = LocalizedText.Tip0;
break;
case 1:
message = string.Format(LocalizedText.Tip1, tips[0]);
break;
case 2:
message = string.Format(LocalizedText.Tip2, tips[0], tips[1]);
break;
case 3:
message = string.Format(LocalizedText.Tip3, tips[0], tips[1], tips[2]);
break;
default:
message = LocalizedText.Tip0;
break;
} %>
<div class="warning">
<%: message %>
</div>
Now I see so much code in my view compared to only a tiny bit of html. This made me worry about whether I'm putting too much logic in my 开发者_运维百科view. However, in a sense all the logic is around formatting the message.
I just wanted to check whether I'm doing this in the right way or not.
Thanks in advance.
What stops you from passing a pair, [Model, Message]
as an actual model to view? Or even create extra wrapper class to pass message together with model. Consider:
class ModelWithMessage
{
public object Model { get; set; }
public string Message { get; set; }
}
as your view model.
This way you can do all the formatting logic in controller and view can remain as simple as it gets.
My point being, all the logic you do in your view currently is view-independant - it rings a bell it should not be there.
Edit in regards to discussion in comments:
Before putting any logic in view, it's good to ask yourself a question: can this be done in my controller/model? Often the answer is yes. Having properly designed model/controller will result in very simple and lighweight views, purely for content display, which is what view should do - accepts necessary information from the controller and renders a user interface to display that (wiki).
Minimalistic view will benefit you later, for example when you realize you need to display same content in other places aswell, perhaps using new view. In your original approach, you'll have to copy logic from the old view into the new view. Copying stuff from one file to another might not sound like a big deal, but let's remember about DRY principle. What if you have 15 views? Do you want to have same formatting logic in all of them? What if your manager comes and tells you formatting has changed? Do you want to update 15 view files, or 1 controller...?
When approaching such problems, it's worth to take a minute and answer yourself questions like those.
精彩评论