我最近开始了一个 MVC 项目,现在似乎每 5 分钟我就面临着关于如何使用这个东西的重大关键设计决策。总是这样,对吧?
我决定将我的领域模型类完全排除在视图之外;它会导致大量看起来相似的 ViewModel,但使用 AutoMapper 我认为这不会是一个问题,而且我认为这是一个很好的干净方法。
然而,我最近的辩论围绕着显示逻辑。假设我有一个MyData
具有 type 属性的模型Status
。这是一个像下面这样的枚举:
public enum Status {
Ok,
NotTooGreat,
CouldBeBetter,
Awful
}
在一个视图中,当我渲染这个模型时,我想输出状态并根据情况的严重程度另外为输出着色。例如,如果是Ok
,我将显示绿色,如果是NotTooGreat
或CouldBeBetter
不是黄色,否则显示红色Awful
。
这个逻辑应该在哪里?最终,颜色选择本身将在视图中(例如,确定要输出的 css 类,该类控制颜色),但确定状态是什么是我认为不应该出现在视图中的决定。可能的选项是:
在自定义 ViewModel 类中使用 DataAnnotations,例如
public class MyDataViewModel { /* Amongst other MyData properties required... */ public StatusViewModel Status; } public enum StatusViewModel { [StatusDisplay(DisplayState.Ok)] Ok, [StatusDisplay(DisplayState.Warning)] NotTooGreat, [StatusDisplay(DisplayState.Warning)] CouldBeBetter, [StatusDisplay(DisplayState.Error)] Awful }
这意味着我的映射相当愚蠢,只能按值映射枚举。然后,视图将依赖 HtmlHelper 根据 DataAnnotation 更改输出。这看起来相当简单,但是这是否在 ViewModel 中放置了太多的“业务”逻辑?也就是说,这不只是一个 UI 问题,因此 ViewModel 定义显示状态是完全有效的吗?我可能会以这种方式最终获得大量自定义 DataAnnotations 吗?如果我还需要说明用户可以根据当前状态执行哪些操作,这些是否会变得臃肿?
保持 ViewModel 简单,并依靠 Mapping 代码来容纳逻辑:
public class MyDataViewModel { /* Amongst other MyData properties required... */ public string StatusText; public DisplayState Status; }
这意味着 ViewModel 不知道什么状态与什么 DisplayState 相关联,它只知道可能存在哪些不同的 DisplayState(即 Ok、Warning 或 Error)。然而,这需要将逻辑放在映射代码中,这对我来说并不像是“映射”——直到现在,模型 + 视图模型之间的映射一直是控制器非常直接的调用——但也许这是一种不必要的恐惧?
这应该在视图中,ViewModel 应该与 Model 保持相同,然后 View 或 HtmlHelper 中的一些代码将根据是什么来决定输出什么类
Status
。
我认为我倾向于数字 1,但我会欣赏其他人的观点。想到的一件事是,这是一个非常简单的示例,但是如果视图要复杂得多怎么办?比如说,如果MyData
状态为Ok
,我们想从模型中向用户显示更多属性MyData
,或者也从其他模型类中提取数据?