在ASP.NET MVC中处理控件显示逻辑的推荐模式是什么?

时间:2011-05-21 11:14:37

标签: asp.net-mvc asp.net-mvc-3

我正在阅读一些MVC3教程,即Pluralsight视频,我正在考虑如果对ASP.NET MVC进行大修,我们现有的应用程序将如何运行(不是计划,但它给了我一个参照系)。在我们的aspx代码隐藏中,我们有相当多的代码看起来像这样:

if (SomeBooleanCheck){SomeControl.Visible = true;}else {SomeControl.Visible = false;}

假设该示例大大简化,但假设布尔逻辑相当复杂并假设需要发生多个事情作为使控件可见(可能更改颜色,大小,文本等)的一部分,这样做的模式是什么在ASP.NET MVC中?看起来你必须在视图本身做同样的布尔检查,这对我来说似乎有些难看。似乎必须有一个更好的方法,这肯定出现在MS的用例列表中,我只是没有看到答案。

2 个答案:

答案 0 :(得分:4)

您可能采取的方法会因具体情况而有很大差异。一些选择包括:

  • 按照您的说法进行操作并在视图中添加条件
  • 将条件(如果它很复杂)抽象到视图模型中,以便视图中的线条仍然很简单(只需访问视图模型上的预设布尔值)。
  • 在路线或控制器级别执行此条件并调用不同的整体视图(可以共享布局(剃须刀)或主视图(webforms mvc))

您没有明确提及如何在条件中呈现控件。我假设你会做一个RenderPartial。所以视图中的线条本身就很小。

if(myViewModel.ComplexBoolean) // Boolean set in generation of view model
    Html.RenderPartial('firstPartial')
else
    Html.RenderPartial('secondPartial')

编辑:如果您设置为“可见”的项目只是一个控件,您可以直接输出控件,例如。

if(myViewModel.ComplexBoolean) {
    Html.DropDownListFor(m => m.Type, Model.Types /* An IEnumerable<SelectListItem>*/, new { @class = "myList" });
}

此外,如果您不想设置'Model.Types'属性(例如保存数据库命中),则条件可能位于您创建视图模型的位置(控制器或某些服务/视图)模型回购)。然后,视图可以检查存在的属性:

if(Model.Types != null) {
    Html.DropDownListFor(m => m.Type, Model.Types /* An IEnumerable<SelectListItem>*/, new { @class = "myList" });
}

答案 1 :(得分:3)

如果您的控件不使用View的ViewModel中的数据,您还可以使用Html.RenderAction调用子操作。例如,假设您要向具有不同角色的用户显示不同的菜单。您可以在视图中调用 @ {Html.RenderAction(“菜单”,“帐户”);} ,这将在“帐户”控制器中调用“菜单”操作。您的复杂布尔逻辑和制定控制器设置的逻辑将驻留在“帐户”控制器的“菜单”操作中。 “菜单”操作将决定要显示的部分视图/控制器。

// 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);
    }
}