我对域/应用程序逻辑和用户界面逻辑感到困惑。为了说明我想要确定的内容,我将在下面描述一个虚构的程序用于说明目的:
(1) 想象一个带有一组3级联下拉菜单的小应用程序。当您选择一个下拉列表时,它会触发一个jQuery Ajax GET,最终命中MVC控制器,提供先前选择的下拉列表的选定值。控制器返回下一个下拉列表的允许选择。 javacript(在视图中)将这些结果排列成下拉列表。等等。因此,每次选择下拉列表时,都会填充下一个。
(2) 现在扔扳手..有一些例外。假设用户在第一个下拉列表中选择“FOO”或“BAR”,则行为会发生变化,因此第二个下拉列表将被禁用,而thrid下拉列表将显示一个texbox。
我的问题是,在MVC的背景下,这个“决策”逻辑的适当位置是什么?比如负责做出这些决定的代码就像我在(2)中解释的那样。我一直把这个放在最方便的地方是在视图的javascript中。我只是编写了javascript来测试第一个框是“FOO”还是“BAR”然后,禁用第二个dropwdown,并换掉文本框的第三个下拉列表。但这对我来说并不合适。因为它似乎应该是业务逻辑,因此代码应该属于某个地方的域层。但这也不太合适。
所以我觉得我要进入圈子。有人可以对这个小设计有所了解吗?
答案 0 :(得分:7)
让我们从域模型开始吧。域模型是以与技术无关的方式对域进行建模的API。它对View技术一无所知,例如JQuery,HTML或(就此而言)XAML或Windows Forms。
域模型包含描述域的类和接口,并允许您以丰富且富有表现力的方式为域概念建模 - 无论您正在开发何种类型的应用程序。
考虑到这一点,很容易看出您描述的显示逻辑不属于域模型。因此,它必须属于特定于UI的层。
您可以将它放在单独的 UI Logic 模块中,也可以与UI应用程序一起使用 - 在您的情况下是ASP.NET MVC应用程序。无论您是在JavaScript中还是在服务器端表达所需的UI逻辑都不太重要。
就个人而言,我会在Partial Views中定义这个逻辑服务器端,但那是因为我非常关心可测试性,而且我知道如何对这种行为进行单元测试(我被告知可以单元测试JQuery代码同样,但我不知道这是否真实。)
如果您最终编写了基于相同域模型的另一个应用程序,那么显示逻辑很可能会变得非常不同,因为不同的技术意味着不同的范例。
答案 1 :(得分:2)
没有分裂太多毛发或过于狂热必须做些什么来保持图案纯粹 ...
显然,Controller知道必须进行此更改,因为它将处理两个结果案例(下拉选择或文本输入)。因此,在控制器中放置与此相关的逻辑是而不是罪。
同样显而易见的是,View必须根据第一个下拉列表的内容更改其显示方式。虽然这种混合行为并不是我能想象到的最好的UI体验,但如果需要必须,那么这个逻辑必须在UI中存在一定程度。但是,jeez伙计们,这是我们在这里讨论的网站。你真的想从javascript中删除所有逻辑并将其移动到控制器方法中吗? View正在决定如何显示数据,这是它的工作,所以不能成为罪恶。
避免被焚烧的真正方法是重新设计以避免争议。或者,只需对啤酒的糟糕设计要求进行编码和唠叨。
答案 2 :(得分:1)
在你发生非常专业的行动的情况下,你需要把它放在js中的逻辑中,就像你在下拉示例中所做的那样。您也总是希望将验证放在服务器端,以确保您的数据是干净的。
随着MVC 2的推出,他们有了一些非常好的验证服务器/客户端验证。查看Scott Gu的帖子对此有更深入的了解:MVC 2 Blog Post
答案 3 :(得分:0)
鉴于你的例子我不介意控制器中的这个逻辑,它绝对不属于域模型。我个人觉得最好抓住控制器中的ajax GET请求并决定用JSON输出什么而不是在jQuery中做所有逻辑(我只是觉得在C#中更舒服然后在javascript中)。说到这一点,我喜欢保持我的动作方法变瘦,所以我要做的就是把逻辑放在一起弄清楚在控制器上的方法中填充下拉列表的内容并用[NonAction]装饰它。