- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个大型Silverlight应用程序,该应用程序使用双工Net.TCP与WCF后端通信。我正在将这个应用程序从MVC方法迁移到MVVM。但是,我正在为实现ViewModels的正确方法而苦苦挣扎。我们将WCF生成的代理用于我们的模型,该模型非常复杂,涉及数十个类,大量集合以及各种多对多关系。例如,一个用户可以属于多个房间,一个房间可以具有多个用户,一个用户可以具有多个SharedFiles,并且每个SharedFile可以与该用户当前所属的任何Room共享。诸如此类的事情。
最重要的是,因为我们在双工模式下使用WCF,所以对模型的更改既可以由最终用户触发,也可以由后端的WCF服务触发。换句话说,我们所使用的模型比您在各种MVVM书籍/文章/博客文章中所看到的典型“模型”要复杂几个数量级。这就是问题所在,因为使我们的ViewModel层与基础Model层保持同步变得有点麻烦。
这是一个典型的问题。新的“用户”加入了“房间”,因此WCF服务向房间中的所有其他用户触发“SessionAdded”通知。 SessionAdded通知带有一个Session对象,该对象具有一个链接的Room和一个链接的User对象。从WCF服务反序列化的这个Room对象与本地客户端上的Room对象基本相同,并且可能具有大多数相同的数据,但是它当然不具有所有相同的数据,至少其中一些数据(例如其空白的Whiteboards集合)肯定是错误的。因此,我们需要以某种方式获取这些传入的数据并将其合并到我们现有的模型中。然后,我们需要在每个新对象的顶部创建ViewModel,和/或使用新对象和/或其数据更新现有的ViewModel。
现在,我们正在通过使各种ViewModel响应相关的WCF通知事件来处理此问题,并尽力修复其基础模型和相关的View模型。我们已经找到了一些技巧,例如SynchronizedObservableCollection(有点像here),它监视(说)Room.Sessions ObservableCollection并自动创建相应的SessionViewModels并将其放置在RoomViewModel.SessionViewModels集合中。我们还使用了ViewModelFactory,它可以缓存 View 模型,并确保包装了给定Session的SessionViewModel保持不变,即使基础Session对象被更改了也是如此。 (如果重要的话,我们使用的是viewmodel-first方法,因为我们需要的大部分工作是创建新的UI元素,以响应由WCF通知触发的ViewModel的更改。)
而所有这些工作。基本上。大多数时候。你知道。但是要维护的代码很多,而且很容易出错。只要您能记住应该发生的事情,单元测试就很方便,但是到完成第20个级联CollectionChanged事件的处理时,很难跟踪所有这些如何组合在一起以及首先要测试的内容。换句话说,它们都非常脆弱。
在我看来,这是很多人必须遇到的那种情况,我很好奇其他人如何面对它。我可以想到几种方法来使它变得更好:
(1)将客户端模型视为需要保持完全一致的一种数据库,并实现一个客户端数据访问层,其任务是保持模型一致。无论是来自用户还是服务器,所有对模型的更新都需要经过这一层。这有点像 Entity Framework ,因为myRoom.Users.Add(myUser)
将自动设置myUser.Room = myRoom
,反之亦然,依此类推。 (尤其是这部分内容似乎应该已经在某个地方发展了,尽管我还没有找到。)
(2)依靠Truss或Obtics之类的东西,使所有片段保持同步。尚不确定该如何工作,但理论上听起来应该可行。
还有什么?我对用于解决此问题的模式或框架感到好奇。
最佳答案
我了解您的痛苦-我目前正在使用MVVM模式开发复杂的数据可视化应用程序。要问自己一个非常重要的问题是:“ View 模型是否会在您使用的所有地方都增加值(value)?”,换句话说,是否存在将模型层的属性仅转发到 View 的地方?
我经常发现,通常在细节级别(例如,Person对象的属性,Age,Name,Forename)的代码区域中, View 模型实际上根本没有添加任何值,而在更高的类(class)级别中,它通过构造 View /窗口等来增加值(value)。
我倾向于对MVVM采取自适应方法,在顶层(Windows, Pane ,窗体),我总是有一个 View 模型,但是如果 View 模型的各个部分是如此简单,以至于 View 模型没有任何值(value),那么我会将它们公开给他人。直接查看。另外,在某些情况下,您需要直接将模型公开给 View 以提高性能。
最后,如果发现需要重新引入 View 模型来解决棘手的绑定(bind)问题,我写了一个简单的模式mini-MVVM,它应用了本地 View 模型:
http://www.scottlogic.co.uk/blog/colin/2009/08/the-mini-viewmodel-pattern/
希望能有所帮助。
关于silverlight - 保持模型和ViewModel同步的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4903701/
我的应用程序包含两部分:网络部分和 GUI。它的工作方式有点像浏览器 - 用户从服务器请求一些信息,服务器发回一些代表某些 View 的数据,然后 GUI 显示它。 现在我已经将网络部分实现为一项服务
给定表达式字符串exp,编写程序检查exp中“{”、“}”、“(”、“)”、“[”、“]的对和顺序是否正确。 package main import ( "fmt" stack "gi
我想要一个简单的脚本在后台保持运行。目前看起来像这样: import keyboard while True: keyboard.wait('q') keyboard.send('ct
我维护着许多 RedHat Enterprise Linux(7 台和 8 台)服务器(>100 台),其中包含不同的应用程序。为了保持理智,我当然会使用 Ansible 等工具,更重要的是,公共(p
我有一个 winforms 应用程序,它在网络服务请求期间被锁定 我已经尝试使用 doEvents 来保持应用程序解锁,但它仍然不够响应, 我怎样才能绕过这个锁定,让应用程序始终响应? 最佳答案 最好
我正在努力在我的项目中获得并保持领先的 0。以下是当前相关的代码: Dim jobNum As String jobNum = Left(r1.Cells(1, 1), 6) r2.Cells(1
我正在尝试在我的 Canvas 中定位元素相对于我的背景。 窗口被重新调整大小,保持纵横比。 背景随着窗口大小而拉伸(stretch)。 问题是一旦重新调整窗口大小,元素位置就会不正确。如果窗口的大小
一直在玩弄 Hibernate 和 PostgreSQL,试图让它按预期工作。 但是由于某种原因,当我尝试将具有@OneToMany 关系的对象与集合中的多个项目保持一致时,除了第一个项目之外,所有项
我想将某些东西提交到 github 存储库,但我(显然)没有任何权利这样做。我对那个 repo 做了一个分支,提交了我的更改并提交了一个 pull-request。 现在,问题是过了一段时间其他人已经
这是一个初学者问题,我仍在考虑“在 OOP 中”,所以如果我错过了手册中的答案或者答案很明显,我深表歉意。 假设我们有一个抽象类型, abstract type My_Abstract_type en
我们正在开展的一些项目在 jQuery 1.4.2 或更早版本中有着深厚的根基,介于缺乏最新版本的性能优势(或语法糖)、使用现已弃用的方法的耻辱以及部署一个积极维护的库的 3 年以上旧版本,升级现在迫
我看到在FMDB 2.0中,作者为线程添加了FMDatabaseQueue。例子是: // First, make your queue. FMDatabaseQueue *queue = [FMDa
我在 NSScrollView 中有一个 NSTableView。 NSTableView 的内容是通过绑定(bind)到 NSArrayController 来提供的,而 NSArrayContro
我在 TreeView 上有一个节点,我手动填充该节点并希望保持排序。通过用户交互,TreeViewItem 上的标题可能会更改,它们应该移动到列表中的适当位置。 我遍历一个 foreach,创建多个
我从主 NSWindow 打开一个 NSWindow。 DropHereWindowController *dropHereWindowController = [[DropHereWindowCon
我需要放置一个 form 3 按钮,当我单击该按钮时,将其显示为按下,其他按钮向上,当我单击另一个按钮时,它应该为“向下”,其他按钮应为“向上” 最佳答案 所有按钮的属性“Groupindex”必须设
我有一个使用 AnyEvent::MQTT 订阅消息队列的 perl 脚本。 目前我想要它做的就是在收到消息时打印出来。我对 perl 完全陌生,所以我正在使用它附带的演示代码,其中包括将 STDIN
如何在 .NET 应用程序中保持 TreeView 控件的滚动位置?例如,我有一个树形 View 控件,并经历了一个向其添加各种节点的过程,并将它们固定在底部。在此过程中,我可以滚动浏览 TreeVi
我维护了大量的 vbscripts,用于在我的网络上执行各种启动脚本,并且有一些我在几乎所有脚本中使用的函数。 除了复制和粘贴之外,有没有人对我如何创建可重用 vbscript 代码库有建议。我并不反
我有一些关于 Azure 自托管的问题。 假设用户 Alex 在物理机 M 上设置了 Windows 自托管代理。当 Alex 注销且计算机进入休眠状态时,代理将脱机。现在,当 Bob 登录同一台计算
我是一名优秀的程序员,十分优秀!