我只是想知道,如果通过移动复杂的 if else 语句和生成的 html 标记到后面的代码是否违反了一些“MVC”法律?
当面临内联 if else 语句可能变得非常不可读时,这似乎是一个不错的选择。
我只是想知道,如果通过移动复杂的 if else 语句和生成的 html 标记到后面的代码是否违反了一些“MVC”法律?
当面临内联 if else 语句可能变得非常不可读时,这似乎是一个不错的选择。
在你看来有条件并不可怕。我会将它们保留在 ASPX 中,而不是后面的代码中。但是,条件通常表示控制行为。考虑以下 ASPX 代码:
<%if (ViewData["something"] == "foo") {%>
<%=Html.ActionLink("Save", "Save") %>
<%}%>
<%if (ViewData["somethingElse"] == "bar") {%>
<%=Html.ActionLink("Delete", "Delete") %>
<%}%>
这组条件表示控制视图正在处理的行为——即,在错误的位置。此行为不可单元测试。改为考虑:
<%foreach (var command in (IList<ICommand>)ViewData["commands"]) {%>
<%=Html.ActionLink(command) %>
<%}%>
在此示例中,ActionLink 是 HtmlHelper 的自定义扩展,它采用我们自己的 ICommand 规范对象。呈现此视图的控制器操作根据各种条件填充 ViewData["commands"]。换句话说,控制器进行控制。在此操作的单元测试中,我们可以测试在各种条件下会显示正确的命令集。
与快速将一些 IF 放入视图相比,起初这似乎很麻烦。您必须问自己的问题是,“这个 IF 是否代表控制行为,我是否要确保在某些时候不会中断?”
我不喜欢在我的视图中使用类后面的代码。这并不是因为它默认违反了 MVC,而是因为我发现“自然”的方式(至少对我而言)是不同的。
当我面对与纯视图关注点相关的复杂 HTML 标记时,我通常会为类编写扩展方法HtmlHelper
以隐藏复杂性。因此,我有像Html.MoneyTextBox()
,Html.OptionGroup()
和Html.Pager<T>
.
在其他情况下,当出现复杂情况时,我通常会错过控制器的某些内容。例如,与元素的可见性、只读或启用相关的所有问题通常源于控制器可以提供的东西。在这种情况下,我没有将模型传递给视图,而是创建了一个视图模型,它封装了模型和控制器可以提供的附加信息,以简化 HTML 标记。一个典型的视图模型示例如下:
public class CustomerInfo
{
public Customer Customer { get; set; }
public bool IsEditable { get; set; } // e.g. based on current user/role
public bool NeedFullAddress { get; set; } // e.g. based on requested action
public bool IsEligibleForSomething { get; set; } // e.g. based on business rule
}
也就是说,后面的代码是视图的一部分,因此如果它更适合您的需求,您可以自由使用它。
我相信只要它是一个渲染代码并且它在“视图”而不是控制器中,那么将它放在代码后面或内联就无关紧要。只要确保你没有在控制器动作中编写这段渲染代码(这样你就真的违反了 MVC 模式)。
代码隐藏是视图的一部分——如果您想将内容直接放在 ASPX 中还是放在代码隐藏中,这取决于您。MVC 并不意味着您必须在 ASPX 中编写所有丑陋的代码:)。