【亚洲必赢官网】终究是如何,视图模型

1.创制视图模型

种种视图定义三个指标模型能够扶助你追踪视图的实际所需。所以应当为每二个应用程序中的视图定义视图模型类。

作者 Jonathan
Allen
译者姚琪琳

Model-View-ViewModel是
一种架构方式,主要在WPF、Silverlight和WP7开拓里使用,它的对象是从视图层移除大约全数代码掩饰(code-behind)。交互设计员能够小心于采用XAML表明用户体验须要,然后创设和视图模型的绑定,而视图模型则是由应用程序开辟者开辟和爱抚的。

亚洲必赢官网 1

各类视图都应该有贰个视图模型类。能够利用调控器名称和视图名称的一个重组。比方,从Home调节器调用的命名Index的视图,其视图模型对象可能被命名称叫HomelndexViewModel。

 

MVVM是更加的通用的Presentation【亚洲必赢官网】终究是如何,视图模型。方式的三个现实贯彻。MVVM视图模型满含概念模型实际不是数据模型,全数事情逻辑和任何操作都以在模型和视图模型里成功的。有广大框架能够产生这一点,当中一部分是:

2.定义视图模型

更好的做法是,能够在Models文件夹中创设一个名称为Home的子文件夹,并在其间树立贰个IndexViewModel类。


“视图模型(View-Model)”那几个术语出现之后,比非常多开采者都有无数疑问。视图模型需求管理视图、模型和表面服务间的重合的标题,那或多或少是分明的,但标准的做法却反复被一笔带过。它应当满含怎么样内容,不应有包涵哪些内容,未有明晰的列表,它们往往最终会化为独具东西的杂炖。本文无意给出分明的答案,而是要切磋视图模型所承受的相当多剧中人物中的多少个。

开源的

class BlogViewModel extends ViewModel {     public $viewFields = array(       'Blog'=>array('id','name','title'),       'Category'=>array('title'=>'category_name','_on'=>'Category.id=Blog.category_id','_type'=>'RIGHT'),       'User'=>array('name'=>'username', '_on'=>'Blog.user_id=User.id'),     );   }

 

在您读书本文中的分歧角色和情势的时候,请牢记以下三点:

  • PRISM:由微软提供,和MEF/Unity一齐用于倚重注入,扶助组合命令,能够扩充。MSDN上有详细的学科和排练。 
  • MVVM Light Toolkit:有visual
    Studio和Expression
    Blend的种类和项的沙盘。愈来愈多信息请看这里,另外能够参见VS和Expression
    Blend的应用教程。
  • Caliburn
    Micro:帮衬视图模型先行(ViewModel-First)和视图先行(View-First)三种开辟方式,通过co-routine帮助异步编制程序。
  • Simple MVVM
    Toolkit:提供VS项目和项的模板,依赖注入,协助深拷贝以及模型和视图模型之间的习性关联。
  • Catel:富含项目和项的模版,用户控件和厂商类库。支持动态视图模型注入,视图模型的推迟加载和评释。还帮助WP7专项使用的视图模型服务。

3.数据库语句:

那么怎么样开拓三个视图模型类呢?

  1. 那些示例都来自下马看花项目。
  2. 大多数视图模型都会承受八个角色。
  3. 严加坚守有些格局的重大低于可运维的程序。

闭源的

Select    Blog.id as id,   Blog.name as name,   Blog.title as title,
   Category.title as category_name,
   User.name as username 
   from think_blog Blog JOIN think_category Category JOIN think_user User    where Blog.category_id=Category.id AND Blog.user_id=User.id

率先,视图模型对象是三个唯有数量而(大致)没有表现的平凡数据传输对象,视图模型对象上的特性会全盘以视图所希望的格式公开数据,它只提供视图所需的数码。围绕视图而非数据来规划视图模型类的构造往往是条件。换句话说,应该援助于把视图模型类设计为二个器皿。视图模型类,最终是为视图建立模型,并非为数量。

模型端的剧中人物

为视图提供数据是视图模型至关心注重要的角色。可是,纵然照旧选取XAML数据绑定本事,提供数据的法子也是二种各个的。

  • Intersoft
    ClientUI:付费的,只帮助WPF和Silverlight,但是,除了MVVM框架,它还提供其他一些表征。
  • Vidyano:无偿但不开源。带有实体映射/虚构长久化对象(数据容器),业务准绳以及内置基于ACL的安全特点。

 4.运用视图模型:

帮忙使用贰个视图模型对象时,必须在视图模板中宣示该视图模型类型。如在视图模板中注明:@model
xxxxViewModel。

用视图模型替代数据上下文

用视图模型代替数据上下文是最轻便易行的模型端(model-side)格局,或者也是最广大的。真正的多寡通过视图模型的贰个或八个简易的特性暴流露来。
在某种程度上,那而不是形式。它只是将视图模型和视图的真正数据上下文属性关联起来,並且注入别的作用,如包装导航或服务调用的ICommand。本文前边还交涉谈那一个话题。

若想打听MVVM,能够参照以下资料:

 

最终,但全体更加好可重用性和预期越来越长使用寿命的大型项目中,大概要以所运用的有着视图模型类来创建四个独门的类库。在小品种中,大概需求把具备的类隔开分离到三个特定的文书夹中。能够在Models文件夹创造三个ViewModels文件夹,并将其按调整器设置专门项目标子文件夹。

将视图模型作为移动记录

可惜的是,“将模型作为移动记录(Active
Record)”是三个科学普及的错误情势。在这种形式下,应用程序中从不真的的模子。相反,全数的字段都由视图模型本身直白提供。
举例,CustomerViewModel恐怕带有FirstName、LastName、CustomerId字段。由于那是一个视图模型,所以很大概还挂接了表面服务。可以经过LoadCustomerCommand和SaveCustomerCommand等ICommand将她们暴揭穿来,那就将视图模型成功地调换成运动记录。

要求注意的是,活动记录情势自己在一些场景下是一定实惠的。难题是,活动记录的用处一定水平上被夸张了,若再让它们担负视图模型的别的剧中人物,就大约成了“万能对象(god
object)”。

亚洲必赢官网 2

如图所示,单元测验未有安身之处。你能够经过行使附带模拟(mock)服务的合龙测量检验来创设虚构的单元测量试验,但这种方法往往非常耗时,并且轻巧出错。

如果未有模型,就不是MVVM。

  • Laurent Bugnion的《Understanding MVVM
    Pattern》和《Deep
    Dive MVVM》
  • 微软Silverlight组的《Understanding the MVVM Pattern in Silverlight
    Applications》
  • 亚洲必赢官网,Erik Lebel在InfoQ上的录制解说《Presentation
    Pattern》
$rows = $Blog->where(array('cid'=>array('IN' , $cateList)))->select();

例如:

将视图模型作为适配器或装饰器

视图模型能够看作适配器(adapter)或装饰器(decorator),以有的时候包装多个模型,提供额外消息或新格式。不过,那是十分危险的试行,只要有异常的大大概就应该幸免。

笔者们选拔卓绝的FullName来作为示范,那样做会推动三种高危机。

使用MVVM的最大好处之一是分离关切点,以便用户体验设计员和应用程序开发者能够并行专门的工作。另一方面,相关的焦躁富含它对于UI操作相比轻巧的气象有一点点杀鸡用牛刀的认为,数据绑定有一点点麻烦调节和测验,以及大气使用数据绑定大概带来质量难点等等。

 

Models》ViewModels》调整器名称》IndexViewModel.cs

基于推送的包装器

在依附推送的包装器(wrapper)中,咱们要是唯有视图模型能向视图推送数据更新。

public class PersonViewModel : INotifyPropertyChanged
{
    private readonly Person m_Model;
    public PersonViewModel(Person model)
    {
        m_Model = model;
    }

    public string FirstName
    {
        get{ return m_Model.FirstName}
        set
        {
            m_Model.FirstName = value;
            OnPropertyChanged(new PropertyChangedEventArgs("FirstName"));
            OnPropertyChanged(new PropertyChangedEventArgs("FullName"));
        }
}

那表示,假使不经过PersonViewModel包装器而平素更换模型,此操作就能够停业。这一个更改不会传出到视图,导致同步难题。



Models》ViewModels》调控器名称ABCD》ABCDsyViewModel.cs

据他们说事件的包装器

据悉推送包装器的二个代表方案是,依赖由模型引发并由视图模型转载的风浪。如下边包车型地铁代码所示:

public class PersonViewModel : INotifyPropertyChanged
{
    private readonly Person m_Model;
    public PersonViewModel(Person model)
    {
        m_Model = model;
        m_Model.PropertyChanged += Model_PropertyChanged;
    }

     public string FirstName
    {
        get{ return m_Model.FirstName}
        set { m_Model.FirstName = value; }
    }

     void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        OnPropertyChanged(e);
        switch (e.PropertyName)
        {
            case "FirstName":
            case "LastName:":
                OnPropertyChanged(new PropertyChangedEventArgs("FullName"));
                break;
        }
    }

在此方案中,从模型向视图模型附加属性变化布告是存在高危害的。当同一个模子被多少个视图模型访谈时,将大概出现内部存款和储蓄器走漏。

(点击图片放大)

亚洲必赢官网 3

基于XAML的控件通过监听模型事件可摆脱该难点,因为数量绑定基础架构(infrastructure)可以制止内部存款和储蓄器走漏。而在WinForm中,能够行使组件的基础架构释放(dispose)事件管理程序。可是,视图模型的生命周期并不借助于于控件,也不可能依赖于控件,因为控件能够再一次加载,由此,它未有适度的地点供大家释放这么些事件管理程序。

那未必就是难题。要是你百分百规定未有另外东西有所到模型的引用,就足以应用视图模型包装器。但更安全的做法是进步模型本人(如将FullName属性放到模型内)或使用值转变器。那三种方法还是能够令你在不涉及视图模型的情状下编写制定单元测验。

若果视图模型监听模型中的事件,将要检讨是或不是会生出内部存款和储蓄器败露。

乔恩athan Allen在研商里提到几点错误选取MVVM的先兆:

将视图作为聚合根

依靠维基百科,聚合在天地驱动设计的词条中被定义为:

与有些根实体对象绑定在一同的目的集结,那个根实体对象也叫聚合根。聚合根通过禁止外界对象具有对其成员的引用,来担保聚合内所爆发的变动的一致性。

聚合根与适配器或装饰器的要害差距是,其模型永久不会暴光。你根本不可能访谈任何模型、模型的属性或事件。独有聚合根持有对模型的援引,由此能够完全幸免上一节看到的内部存款和储蓄器败露。

一旦视图模型完全隐形了复杂对象图的内部原因,那么它也许是二个聚合根。

  1. 你的模型和视图模型名字同样。

将视图模型作为Web MVC模型

那是自己在ASP.NET
MVC社区中看出的一个冲突较新的地方。相当多开拓者把由调节器成立或加载,并传递给视图的类叫做“视图模型”。那是与“领域模型”和“输入模型”相对应的。Dino
Esposito的篇章“ASP.NET
MVC应用中的两种模型”很好地解说了那或多或少。

那类别型的视图模型很轻巧辨认,因为它除了含有数据和完全凭借于数据的工作准绳外,不富有别样任何剧中人物和职责。因而,它有着其余纯模型所独具的有着优点,如易于单元测量试验。

那时候就不曾须要责备这种命名方式了。如同守旧MVC和Web
MVC之间的界别同样,那是我们只可以承受的习贯之一。

注意不要混淆“视图的模子”和“视图模型”,特别是MVVM应用程序大概带有这二种模型。

视图模型不应有是对模型的卷入。视图模型的职务是表面服务的央求中介,比方加载和封存数据。而数据作者,以及表明和大好多政工逻辑应该投身模型里。

视图端的脚色

视图和视图模型之间存在分裂水平的耦合。我们先来拜访最紧凑的耦合,然后探讨更理想化的视图模型。

本人时常重申那一点。每当你创设三个视图模型包装贰个模型,你就在你的API里引入三个巨大漏洞。具体地,任何直接援引这么些模型的事物都只怕以视图模型无法察觉的主意退换某些属性,因而UI也不会有相应的改换。同样地,模型里总括字段的别的变动也不会回传给视图模型。

将视图模型作为代码掩盖

对于XAML初学者的话,往往会犯八个反形式错误。大家常说在“xaml.cs”或“xaml.vb”个中不该放入过多的代码。善良的初学者平时将其误解为无法归入任何代码。因而,他们将有着东西都扔进“视图模型”,使其改为一种放错地方的代码掩饰文件。

此刻,借使把装有东西都扔到代码隐蔽文件中,所面对的题目是一模二样的。另外,把全部东西都扔进视图模型还会使得静态深入分析更加艰辛,并且带来内存走漏的或者。

假设将全体的代码从Xxx.xaml.cs移到XxxViewModel.cs,视图模型就改成了“代码掩盖”文件。

  1. 你的视图和视图模型名字一样。

将视图模型作为守旧的MVC调控器

历史观MVC和Web MVC一个第一的区别在于调控器和视图的涉及。在Web
MVC中,调控器能够成立并回到它想要的任何视图。除了为那些视图提供数据模型之外,与它们未有任何交互。

而古板的MVC视图和调整器则连接紧凑耦合在一同。各种调整器都以特意创设的,为有个别特殊视图的用户生成的平地风波提供劳务。这种方式也出现在MVVM中,视图模型扮演调控器的剧中人物,而ICommand则代表了风云。

将视图模型作为调控器和将其看做代码隐敝文件之间的差别十一分微小,由此有点通用的清规戒律:

精粹的景色下,视图模型是不掌握使用它们的视图的,特别是WPF应用程序有八个窗口分享一样的视图模型。

将视图模型作为调整器的注明

  • 用ICommand管理外界能源
  • 因而揭露附加属性的方法来触发可视状态(Visual
    State)的退换
  • 当众了控件可以响应的习性和事件
  • 只侦听视图上的形似事件,如Loaded和Unloaded

对此拾叁分小型的应用程序来讲,整个应用程序大概只需八个视图模型。对于非常的大型的应用程序来讲,首要功用或然须求二个视图模型,各样次要方面也要求三个,比方配置管理。

将视图作为代码掩盖文件的标记

  • 动用伊夫ntToCommand处理视图模型中的全数事件
  • 经过一向调用可视状态管理器(Visual State
    Manager)的方法触发可视状态的变动
  • 一贯与控件交互
  • 重视于视图的实际布局
  • 为了让视图模型精确专业,公开了控件必须响应的风波上面包车型地铁层关系图展现了决定器式和代码掩盖式视图模型的两样。

(点击图片放大)

亚洲必赢官网 4

调控器和代码遮盖之间的这种分歧对应用程序本人来讲影响相当小,但一旦要对视图模型举行不借助于于视图的测量检验,这种差别就显现出来了。即使自身不赞同对视图模型这样的集成组件实行单元测验,但试行集成测验来确定保证其与外界能源(数据库、Web服务)平常干活将是老大有救助的。视图与视图模型之间的这种双向耦合将使集成测量试验变得进一步不便。

设若视图模型与视图之间是一对一映射的,那么视图模型就成了一个调节器。

  1. 你未曾代码遮盖。

将视图模型作为分享的调整器

席卷自身在内的成都百货上千人都宣传,借使视图模型不能被四个视图共享,就不是实在的视图模型。就算笔者前日对那么些理论不那么教条了,但本身依旧将其正是三个实用的设计情势。

假定您要在多少个使用同样数量的视图之间开始展览共同,就足以应用分享调节器方法。比方,有些窗体中有二个数量网格(data
grid),另三个窗体中有一个来得那么些多少的图纸。这时你能够直接分享模型,但分享视图模型却更不至于犯错。那样,倘诺您切换来完全不一致的数据,多少个视图将同临时候被报告。

亚洲必赢官网 5

细心,分享的视图模型写起来要比调控器式的视图模型难得多。何况它们还特别不活络,你无法不在代码隐蔽文件中放入比平常越多的代码。其好处是,分享的视图模型更便于测验,因为它们必然排除了大多千头万绪。

贰个管用的代替方案是,在观念的MVC格局中对模型(而非调整器)举行分享。XAML数据绑定能很好地支撑那三种设计,由此就看哪一类方案对完全统一筹算的破坏性越来越小了。

若是将视图模型设计为分享的,它们将更便于测量检验。

代码遮蔽既非四个好的东西,亦非一个坏的事物。它只是多个用来放置和视图或控件相关的逻辑的地点。因而,当自家看齐三个视图未有别的代码隐蔽,笔者就能够立马检查是不是留存以下难题:

将视图模型作为导航器

4个基本点的基于XAML的UI框架都包蕴导航风格的应用程序,但Windows
Phone或Windows 8
Metro应用则对它越是情之所钟,因为在这一个使用中,导航框架都处于宗旨地方。

有幸的是,借使用别样东西(如顶层视图模型)来包装导航框架,也不行适于单元测量检验和购并测量试验。当接触页面转移时,视图模型不会将U途胜I发送给导航框架,而会发送给二个得以检查的模拟类。能够参考格Rani特e.Xaml的NavigatorViewModel和SimpleNavigator类。

抽象的导航框架对于构建可测量试验的视图模型来讲是根本的。

  • 视图模型是或不是通过名字接触了一定的控件?
  • 视图模型是不是通过命令参数访问控件?
  • 是还是不是采纳了伊夫ntToCommand或别的能够导致走漏的行为并不是轻巧的事件管理程序?

将视图模型作为MVP的体现器

模型-视图-体现器情势与守旧MVC形式最珍视的界别在于模型和视图间的交互情势不一致。在MVC格局中,模型直接触发视图监听的风云。而在MVP形式中,显示器监听事件,并更新视图本人。

出于XAML拾分强劲,在所切磋的手艺中,大家差相当少开采不到这种格局的存在。但其实它在二十多线程应用程序中扮演了重大的角色。

当模型在并未有其他用户交互的动静下被后台线程更新时,日常会用到这种情势。在这种意况下,视图模型担负将公告封送(marshal)给UI线程。那说不定会波及将数据复制给多少绑定的模型,或直接更新控件本人。

值得注意的是,那并非拍卖二十四线程的独一方法。假诺计算复杂度不高,最佳轻松地将具有异步新闻封送到UI线程,并在这里实行拍卖。一些库(如响应式扩充)可以简化这一个操作。

思量选择展现器形式来担保不在UI线程中拍卖异步音信。

MVVM
Light的EventToCommand很有标题,因为它会使得控件从显示器移除之后不或者被垃圾回收。

服务/能源剧中人物

到如今停止,大家都将“外界服务”作为黑盒,它象征应用程序或者需求拜会的文件系统、数据库、Web服务以及别的外部财富。今后,到了该思虑怎么着确实访谈那些劳动的时候了。有二种为主的措施得以兑现那或多或少。

  1. 视图模型监听属性更换文告

将视图模型作为数据访问层

对于小应用和概念突出的外界服务,通过视图模型直接调用是特别轻巧的。这种模型对于简易利用是丰硕优良的,并且WCF珍重接口的规划使得达成依赖注入变得尤为便于。

这么做的短处是紧缩性远远不够好。随着应用程序越来越复杂,你会意识视图模型中的逻辑更是多。在.NET
4.5引进async/await关键字之前越来越如此。

借使您意识你的视图模型被回调逻辑搞得不堪重负,就足以思考增多三个独门的客户端服务层。

亚洲必赢官网 6

只顾,在使用这种方式时,比非常多开辟者会选取放任将表面服务作为特殊的组件举办测验。其辩白是,虽然唯有视图模型能够访问服务层,那么针对视图模型的测量检验就能够並且背负测量检验服务层的天职。

WCF接口是依赖注入和效仿的完美选拔,非常是当应用程序不含有单独的数码访谈层时。

一旦贰个模子的的生命周期比监听它的事件的视图模型长,那么或然引致内部存款和储蓄器败露。不相同于视图有个Unloaded事件,视图模型对于生命周期管理未有很好的方案。由此借使它们关联到现成期比它们越来越长的视图模型的风云,视图模型将汇合世泄漏。

视图模型扩张少访谈层

有二种情状你恐怕供给独自的多寡访谈层:

  • 视图模型变得过度庞大,很难保证。
  • 在两个视图模型之间重复雷同的外表服务逻辑。

这种方式很难写正确。如若在概念应用程序中DAL和VM的一定剧中人物时不加注意,末了也许持有逻辑都会放在DAL或VM之中。那不单背离了该格局的本意,何况当维护者看到差相当的少为空的组件作为没要求的标准代码时,也会深感非常迷惑。

亚洲必赢官网 7

在编辑集成测量检验时,你有三种采取。能够像在此以前那么针对视图模型,同不时候测量检验这五个零件。恐怕,也足以本着数据访谈层。

后面一个的优势在于为大家提供了引进基于接口的依赖注入的一清二白的做法。反过来,它使我们得以应用模拟的单元测量试验对视图模型实行测量检验。

查阅葡萄牙语原稿:MVVM Frameworks For
.NET

结论:精晓视图模型

确实主宰视图模型并幸免其变为杂炖的独占鳌头路线是,先决断该术语对您的话具体意味着什么。列出全数关心点,看看它属于哪个组件。

上边那些示例来自自个儿的四个应用程序;你的列表可能那几个相像,可能会完全差别。

关注点
组件

在页面间导航
着力的视图模型(Silverlight导航框架)

格式化
视图(值调换器)

在视图中展现对话框
视图代码遮蔽

加载重视项
主导的视图模型

创办调控器
基本的视图模型

触发WCF调用来加载或保存模型
视图特定的调节器

证实用户输入
模型(INotifyDataErrorInfo)

错误报告
着力的视图模型

理之当然,该表格只含有客户端代码。对于确实的花色,还索要树立五个如此的报表,贰个为服务端代码,另叁个意味哪个数据表对应哪个数据库架构。随着项指标提升和策画的嬗变,供给更新那些报表以影响新的代码,或重构代码直到再也符合那一个报表。如此一来,我们连年能在增多新作用在此以前就知晓它们所属的机件。

万一能从本法学到点主张的话,作者愿意是:

设计方式仅仅是提出;怎么样将其转化成实际的安排以满足你的须要,完全都是由你来决定的。

网站地图xml地图