通用视图模型?

5

我在想,是否将一个通用的视图模型作为视图的输入是一个好的实践?

我这样想是因为有人提到,除非他开始制作通用视图和通用视图模型,否则他预计会做很多重复的代码。

所以基本上视图只是一组控件。一个视图可能有2个控件(比如文本框和单选按钮),另一个视图可能有50个控件。

它们都具有相同的外观和感觉(只是随着控件数量的增加而增长)。基本上,他认为视图模型接收对象(域对象),查看它并查看50个字段,然后呈现正确的控件类型。

我猜编辑模板可以用于确定控件,但我对通用视图模型还没有完全信服。

我喜欢泛型,它们可以做很强大的事情,在某些情况下它们很好,但总体而言我并不是特别喜欢它们,尽量避免使用。

我发现大多数时候它可以减少重复代码,但有时它会使代码变得更加复杂。当然,这可能只是因为我还是一个相对新手程序员,可能还超出了我的技能水平。

我对它的下一个问题是,我认为视图模型应该尽可能扁平化,并且仅公开实际将要使用的数据,以便人们不会开始使用本来就不应该出现在视图中的属性。

我对它的下一个问题是,如果您有一些包含对象的复杂对象,则它可能会继续下去。它可能会持续很长时间。


请看一下我的代码,我试图实现类似的功能。链接 - Omar
4个回答

5
个人而言,我避免在视图模型中使用泛型。我同意你提到的大多数反对理由,特别是这一点:
引用:

我对它的下一个问题感到困扰,我认为视图模型应该尽可能平坦,并且仅公开实际上将要使用的数据,以便人们不会开始使用本来不应该出现在视图中的属性

视图模型的理念是,它们需要与给定视图的要求紧密相连,而不是像您的领域模型那样通用/泛型。与在视图和部分视图中重复使用某些通用怪物相比,我更喜欢在视图模型中复制代码。
即使在需要{{link1:生成动态表单和控件}}的情况下,也不需要使用泛型视图模型。
因此,除非您有某些超级特定的场景(目前想不到任何一个),否则最好避免在视图模型中使用泛型。
这就是说,不要完全排除它们的使用,如果你觉得通用视图模型在某些情况下可能会有用,请不要犹豫在此处提出,通过解释场景并展示所有代码,以便我们进行讨论。

我找到的唯一原因是有人说他有大约200个相似的条目,不想制作200个单独的视图模型和视图。在那种情况下,我不确定该怎么做。另一个我忘记添加的观点是数据注释验证。我猜你可能必须将其放在域对象上,我认为这是另一个不好的做法。http://stackoverflow.com/questions/2138951/asp-net-mvc-generic-view-for-displaying-data -发帖者没有提到View Models,但我认为他可能正在使用它们。 - chobo2
@Darin Dimitrov,我只使用视图模型将数据从视图传递到控制器,而不是反过来。此外,它的页面编号、页面大小、搜索过滤器等仅用于读取,没有添加/编辑/删除操作。有些控制器需要额外的参数,比如ProductCategoryId。我应该使用继承还是在新的视图模型中复制代码以添加额外的字段? - user2330678

3
我认为通用的ViewModel没有任何问题。相比于ViewBag,这是一种去除重复并保持编译时检查的好方法。
例如,假设您有一组与“Product”、“Category”等相关的Model类。每个类(ProductModel、CategoryModel)都有一个关联的显示和编辑模板,可以生成适当的视图。
现在您想构建一组用于查看和编辑的页面。
我通常会创建一个布局(Web表单中的主页)来呈现常见内容(标题、页脚、菜单等)。
然后,我会创建单独的强类型视图,接受ProductViewModel、CategoryViewModel等作为模型。
现在我们需要定义这些ViewModel类。每个ViewModel类应该接受一个ProductModel、CategoryModel等实例(它将传递给模板)。但是布局通常需要一些额外的数据(即选择的菜单、登录用户名等)。我的解决方案是创建一个通用的ViewModel,封装此重复数据以供布局使用。
public class EntityViewModel<T>
    where T : EntityModel
{
    public T Entity { get; set; }
    public string UserName { get; set; }
    public string SelectedMenu { get; set; }
}

然后,您可以轻松创建一个ProductViewModel:EntityViewModel<ProductModel>,其中包含布局需要呈现页面的所有内容,并且您可以在那里添加任何其他特定于产品的数据。

@ Jakub Konecki - 你能给个例子吗?我很想至少看一个例子,看看它会是什么样子(也许它完全不同于我想象的)。 - chobo2
Entity现在是ProductModel还是CategoryModel,还是ProductViewModel和CategoryViewModel? - chobo2
@chobo2 - 正如你在最后一句中所看到的 ProductModel : EntityModel - Jakub Konecki

1
就ViewModel而言,我通常让所有的ViewModel都继承自一个BaseViewModel,该ViewModel公开了一些有助于实现MVVM的方法。如果您想看一个例子,请在下面评论。

1
你在ASP.NET MVC应用程序中使用MVVM模式吗?嗯,我也很想看看这方面的例子。 - Darin Dimitrov
很想看一个例子。我不熟悉那个模式。 - chobo2
我一开始没有看到asp.net标签,我以为你是在使用Silverlight之类的MVVM而不是MVC。 "视图模型"在MVC中有用吗? 我通常只看到视图和模型作为单独的实体。 - Nick Heidke

0

我真的不喜欢在 ViewModel 中放置业务逻辑。我认为除了常规属性和构造函数内的错误处理之外,ViewModel 中不应该有任何东西。这使得代码更清晰,您可以更自由地向 ViewModel 添加内容。 如果您有太多重复的代码,可以将其隔离到单独的 ViewModel 中,然后在需要它的位置嵌套它。 这样,您的视图中也只有您需要的内容。


6
问题中并没有提到在ViewModel中包含逻辑。 - Andrew Barber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接