I'm going through some of the MVC3 tutorials, namely the Pluralsight videos, and I'm thinking of how our existing application would function if it were overhauled to ASP.NET MVC (not the plan, but it gives me a frame of reference). We have qu开发者_如何学Goite a bit of code that looks something like this in our aspx code-behinds:
if (SomeBooleanCheck){SomeControl.Visible = true;}else {SomeControl.Visible = false;}
Granted that example is greatly simplified, but assuming the boolean logic is fairly complex and assuming multiple things need to happen as part of making the control visible (maybe changing color, size, text, etc.) what's the pattern for doing this in ASP.NET MVC? It seems like you'd have to do that same boolean checking in the view itself, which to me seems kind of ugly. Seems like there has to be a better way and this surely came up on MS's use case list, I'm just not seeing the answer.
The approach you may take will vary greatly depending on the specific scenario. A few options incude:
- Doing as you say and adding the conditional in the view
- Abstracting the conditional (if it is complex) into your view model so that the lines in the view are still simple (just accessing a preset boolean value on your view model).
- Doing this conditional at the route or controller level and calling a different overall view (which may share a layout (razor) or master view (webforms mvc))
You don't mention explicitly how you would render the controls in the conditional. I assume you would be doing a RenderPartial. So the lines themselves in the view would be quite 'small'.
if(myViewModel.ComplexBoolean) // Boolean set in generation of view model
Html.RenderPartial('firstPartial')
else
Html.RenderPartial('secondPartial')
EDIT: If the item you are setting as 'visible' is simply a single control you may just output the control directly e.g.
if(myViewModel.ComplexBoolean) {
Html.DropDownListFor(m => m.Type, Model.Types /* An IEnumerable<SelectListItem>*/, new { @class = "myList" });
}
Additionally if you didn't want to set that 'Model.Types' property (to save a db hit for example) then the conditional could be in the location you create your view model (either the controller or some service/view model repo). The view could then just check for the properties existance instead:
if(Model.Types != null) {
Html.DropDownListFor(m => m.Type, Model.Types /* An IEnumerable<SelectListItem>*/, new { @class = "myList" });
}
If your controls does not use the data found in your View's ViewModel, you can also use Html.RenderAction to call Child Actions. For example, suppose you want to display a different menu to users with different roles. You can call @{Html.RenderAction("Menu", "Account");} in your View, which will call the "Menu" Action in your "Account" controller. Your complex Boolean logic and the logic to formulate your controllers’ settings will reside in the "Account" controller's "Menu" action. The "Menu" action will decide what Partial View/Controller to display.
// This goes in your View (clean single line!)
@{Html.RenderAction("Menu", "Account");}
// This goes in your controller
[ChildActionOnly]
public ActionResult Menu()
{
bool isAdmin = false;
// Your complex boolean logic goes here
// Set your controller settings here
string controllerSettings = ""; // Use class or array for multiple settings
if (isAdmin)
{
return PartialView("~/Views/Account/_AdminMenu.cshtml", controllerSettings);
}
else
{
return PartialView("~/Views/Account/_StandardMenu.cshtml", controllerSettings);
}
}
精彩评论