让我们想象一个非常简单的UI,其中有一个复选框列表。当您单击其中的任何一个时:
1)如果未选中,则应使用此复选框名称创建一个工作空间(然后该工作空间中将提供更多逻辑,但这与问题无关)。然后,该复选框自然会被选中;
2)如果它已经被选中,它应该变成未选中状态并且应该销毁相关的工作区。
实现此目的的直接方式是让View
查看所单击复选框的状态,并取决于是否已选择viewModel.createWorkpace()
或viewModel.destroyWorkspace()
。但这意味着该逻辑包含在View
中-我觉得最好将其包含在ViewModel
中。
我已经读到ViewModel
出于各种原因不应该知道View
。但是,一件事并没有对View
的物理依赖性(例如,对象引用),而另一件事完全不同,甚至没有意识到View
可能具有此示例中的复选框。
给我的印象是,实际上View
和ViewModel
的区别并不大,实际上ViewModel
越接近View
,更容易在View
和ViewModel
之间绑定数据。
我应该如何处理这种情况?为什么?
谢谢
答案 0 :(得分:0)
这个想法是将视图和视图模型分离。 您应该能够单独实例化viewmodel。 这样做的主要原因不是一些含糊的整洁之类。 主要原因是您可以通过实例化离散类轻松地对代码进行测试。
该视图应该查看与显示数据和允许用户进行交互有关的内容。 视图模型应该具有对这些交互起作用并向视图提供数据的代码。 这并不意味着视图根本不应该包含任何代码。 但是,如果有代码,则应针对特定视图。 使用行为之类的可重用代码是一个好主意。 因为这样您可以手动测试它们并证明它们有效。然后重新使用您经过验证的代码。 与转换器,验证器等类似。
所有代码。
所有在视图中使用。
我认为从理论上讲,可以编写一个没有转换器,验证器或行为的应用程序。我从来没有见过一个严肃的商业应用程序却没有全部三个。
与对逆向模型相比,对视图模型一无所知的重要性不那么重要。 除非实例化了视图模型,否则您将不会实例化视图以进行测试。 但这并不意味着您应该将所有代码都绑定到后面的代码中。
那到底是为什么? 因为MVVM的上帝会用他的闪电击倒您吗? 不。 因为这样会使将来的开发变得容易吗? 可能吧,但通常不会那么多。
为什么呢? 因为用其控件实例化视图非常慢。 它们不可避免地具有许多您无法嘲笑的依赖项。 它可能取决于应用程序中的资源,因此您必须实例化应用程序并合并资源字典。 视图通常取决于大量的库,图片,用户控件等。 您都无法嘲笑。 所以你需要一切。 到您在某个测试运行器中自动实例化所有内容并熨平按钮等时,... 您的头部会受伤,理论上您会发现,每10分钟要在几秒钟内运行的2000次测试所花的时间要长得多。 如果在测试中实例化视图,则不能“适当”使用TDD。
要回答您的工作区复选框问题。 这取决于实际的工作空间。
常见的模式是在绑定到每个复选框的ischecked属性的viewmodel属性的setter中启动代码。 这可能在每个复选框提供的视图模型中,该视图模型具有工作空间的名称,类型或执行取消选中内容所必需的任何内容。 每个对象都会对它们正在创建的这些东西进行某种形式的引用,以便可以将它们或当被检查的值变为false时进行处理。