据我所知,ViewModel应该从视图中抽象模型并添加额外的逻辑来处理演示文稿。
我的问题是:
如何创建一个数据表单,该数据表单一次处理订单和详细信息的用户输入。 它应该显示输入订单的字段以及1个详细信息的字段。
我的模型将有一个包含OrderDetails列表的订单的对象。
如何为我的OrderEntryForm查看我的ViewModel?
我是否有一个OrderViewModel和一个OrderDetailViewModel和我的 我的OrderEntryForm将包含OrderViewModel的属性和OrderDetailViewModel的属性? (嵌套ViewModels?) 在这种情况下如何处理验证?验证应该接近模型吗? 特别是当我与RIA-Service合作时...... 把它放在ViewModel中会不会更有意义吗?
您从ViewModel中抽取模型的距离是多少? 例如:
private DateTime _OrderDate;
public DateTime OrderDate
{
get { return _OrderDate; }
set
{
if (_OrderDate != value)
{
_OrderDate = value;
OnPropertyChanged("OrderDate");
}
}
}
这意味着我必须将ViewModel-Property映射到Model-Properties。无法利用模型中的验证 - 逻辑...
这个例子:
public DateTime OrderDate
{
get { return Model.OrderDate; }
set
{
if (Model.OrderDate != value)
{
Model.OrderDate = value;
OnPropertyChanged("OrderDate");
}
}
}
需要传递一个模型。可以访问模型的验证逻辑,但也可以访问耦合......
网络上的大多数示例都显示了使用ViewModel的数据形式,这只是表格的表示而不是真正的抽象......
我知道,我看到了这个
stackoverflow.com/questions/744474/combining-net-ria-services-and-mvvm-in-silverlight-3-0
我也在这上面阅读了nikhils blogpost,但这也只处理了从数据库表中直接映射的产品... =(
我知道很多问题......
您对该主题有何看法? 你会如何处理复杂的数据形式?
答案 0 :(得分:0)
克里斯,
我遇到了同样的问题,并最终以一种糟糕的方式实现它:-((每个视图两个vieModel,但将父级传递给子视图......坏东西)。
从我的错误中我知道下次我会尝试:
生成单个ViewModel,但在子视图中传递datacontext中的详细信息实体(此详细信息实体不必与代理生成的实体匹配,也许是该实体的容器)。
生成单例控制器类:此类不会暴露给视图,它对于视图是透明的,只是详细视图模型会向控制器询问该依赖数据而不是转到DAL
不确定这是否是干净的解决方案,必须尝试并失败:)。
我同意你的观点......在这种情况下,没有真正的样本。
您怎么看?
由于 布劳略
PS:关于验证,如果我们创建自己的超级实体,我们可以定义我们的验证,在我的情况下,我尝试使用部分情况扩展实体,然后我可以通过我的特殊验证实现myPhoneNumberDetail。答案 1 :(得分:0)
我个人认为没有严格的规则......好吧,有一个 - 务实。
从语用上讲,视图模型是一个模型,数据模型也是如此。两者都是类,独立于UI,表面状态作为属性,操作作为方法,通知作为事件。在我看来,我认为区分它们的是它们的一般性。我看到一个模型通常可用于多个视图,而不是针对特定视图优化的视图模型。
我个人从不抽象为抽象。我永远不会为每个模型属性显示顶级属性,并通过委托给底层模型来实现它。这增加了工作量。它增加了要测试的代码量。它需要传播元数据,更改通知等。如果有一些实际的逻辑需要添加,那么是的,我会在视图模型上显示属性并在适当时委托给底层模型。即使在那里,我也会问在模型上将它们作为计算属性公开是否合理/合适(视图模型和数据模型都是模型)。
就直接表现DAL类型而言,在我看来,这在某种程度上是正交的。这取决于其他因素 - 您想要抽象DAL多少,DAL类型有多大 - 例如,如果DAL类型有很多外键,表示模型等效或投影可能更有用做了一些非规范化。有时安全性可能是编写演示模型/投影的原因 - 例如。我不想向客户端发送电子邮件地址,而是想要另外表示电子邮件地址。
在我的示例中,我直接使用了DAL类型,以简化并且没有单个样本中的概念重载。我确实想以专门的方式发布有关演示模型和投影的博客......所以不想同时将viewmodel和.net ria服务的帖子与演示模型概念混合在一起。
答案 2 :(得分:0)
正如经常那样,有了模式,这实际上取决于。 ViewModel可以公开底层模型,并且没有严格的规则表明您“必须”隐藏所有内容并进行委托。我已经和许多严格遵守LOD的人交谈了,他们仍然同意在UI绑定的情况下,它不适用。
现在,无论该模型是否是DTO,您都会发现很多不同的意见。有些人认为,客户端唯一应该是纯粹的投影,即所有逻辑都存在于服务器上的DTO,而其他人认为层之间的移动实体很好。这将是对不同帖子的讨论。 : - )
一般来说,我建议的指南总是至少有一个可以用于屏幕状态等的高级VM。
就像OrderDetail这样的子模型而言,如果子模型足以绑定到那么只是直接暴露它。现在要考虑的一件事就是通知,如果你的模型没有实现INPC,你可能别无选择,只能将它包装起来,以便绑定到正常工作。
即使它实现了INPC,也可能存在该模型不包含的视图特定问题,但视图才能运行。在这种情况下,我将使用简单聚合并创建一个OrderDetailVM,它直接公开底层的OrderDetail并添加其他属性。
例如
public class OrderDetailViewModel
{
public OrderDetail OrderDetail {get;set;}
public bool IsValid {get;set;}
}
IsValid正在检查某些特定于屏幕的逻辑。
这实际上取决于你想要实现多少封装。使用委托模型我不会发现任何问题。取决于复杂性,虽然它可能变得难以处理,例如想象如果OrderDetail有额外的孩子等等。
HTH 格伦
答案 3 :(得分:-1)
为了澄清,VM是Model的抽象,而不是View的抽象,而不是相反。
您当然可以使用多个VM来对应View的离散部分。如果您不需要为订单和详细信息单独的VM,您可以只拥有一个包含所有内容的OrderAndDetialsViewModel,整个View将直接与之绑定。这就是抽象的来源。
你是对的,你的模型的验证逻辑将与你的ViewModel的验证逻辑不同,如果你把它放在那里。在任何情况下,验证都不在视图中。
我不确定我是否按照你的第二个例子。什么是 Model对象?您的VM可能知道组成它的模型,但它不会直接将它/它们暴露给视图。
我希望这会有所帮助。如果您的帖子中有任何我未能解决的部分,请告诉我。