Dorado 5 : 2.ViewModel的概念 (T1)

ViewModel简述

ViewModel是一种用于封装界面逻辑和操作逻辑的对象。即视图中包含哪些数据、这些数据以什么方式展现、视图中包含哪些控件、这些控件会激发什么操作等等。我们可以把ViewModel看作是Dataset和各种控件的容器。
ViewModel一般不用于定义各种控件最终在显示的布局,控件布局应通过其它方式进行定义。在通常情况下,我们利用JSP来完成对ViewModel布局的定义。
在dorado中,ViewModel有两种含义,一种是专指ViewModel对象。例如,在ViewModel中,数据的加载是通过Dataset实现的。另一种指在开发平台中进行配置的ViewModel文件。例如,打开ViewModel,新建Dataset数据集对象。

ViewModel的状态

ViewModel对象不会在服务器端进行缓存。我们也可以把ViewModel看成是服务器端同客户端进行信息交换的接口。当用户执行页面请求、局部数据刷新、远程方法调用等操作时服务器端都会创建相应的ViewModel 实例。我们可以通过其state属性来判断当前ViewModel在何种情况下被创建。state有下面几种取值:

  • ViewModel.STATE_VIEW

打开视图状态。即用户请求一个新的视图时的状态。在此状态下ViewModel在创建时会自动创建所有已经定义的Dataset,并自动根据每个Dataset的配置来装载数据。所有的控件(Control)将以懒装载(Lazy Load)的方式被创建。

  • ViewModel.STATE_SERVICE

服务状态。当一个已打开的视图在执行局部数据刷新、远程方法调用等操作时的状态。在此状态下ViewModel中所有的Dataset和控件(Control)将以懒装载(Lazy Load)的方式被创建。

  • ViewModel.STATE_ UPDATING

数据更新时状态。当Dataset被从客户端提交至服务器端处理时的状态。在此状态下仅初始化被提交上来的Dataset。

  • ViewModel.STATE_DESIGN

设计时状态。该状态只有在为dorado studio提供服务时有效。
在多数情况下我们建议使用ViewModel的实现类作为后台业务逻辑的调用接口。一般的,一个dorado JSP都必须定义一个相对应的ViewModel视图模型。

ViewModel中的ViewProperties

ViewProperties是一种对于某个ViewModel来说,无论在Client端还是Server端都可以使用的属性集合,我们可以利用它来实现Server端与Client端之间的数据传递。

  • Client端使用方法

getViewModel(namespace).properties().getValue(key);
getViewModel().properties().setValue(key, value);

  • Server端使用方法

在ViewModel中利用properties()得到MetaData对象。
this.properties().setValue(String key/int index,Object value);
在其他非ViewModel的类中使用DoradoContext对象实现ViewProperties的存取。

  • 借助EL表达式

${ViewProperties.XXX} 或 ${ViewProperties.getString("XXX")}。在Studio开发平台中可以通过ViewModel根节点中的Properties节点来初始化ViewProperties的值。

ViewModel中的实现类

从运行原理我们可以看出,用户配置的XML定义被加载并生成了ViewModel对象,其中包含Control及Dataset对象。如果把ViewModel看作Control和Dataset的容器,不可避免地会在ViewModel中执行对Control和Dataset的操作。例如Control对象的初始化、Control对象的创建以及属性的动态设置、Dataset对象中的数据加载以及从客户端提交的数据的处理等等。
在dorado中我们可以定义一个ViewModel的实现类,通过重写ViewModel抽象类的方法来达到用户操作Control和Dataset对象的目的。
ViewModel中常用的方法并不多,不过它们常常并不是那么容易使用。有一些细节必须保持注意,不然你很可能会写出一些有问题的ViewModel实现类。
通常,我们会在ViewModel的实现类中使用到下面的一些方法。这些方法都来自于父类。在大多数情况下,使用时都需要利用super保留字调用父类中的方法。

方法

说明

void init(int state)

ViewModel的初始化方法。参数为ViewModel当前的状态。

void initDatasets()

ViewModel初始化其中的每个Dataset的方法。实际上,有哪些Dataset会在该方法中被初始化是取决于ViewModel的当前状态的。

void initDataset(ViewDataset dataset)

根据当前不同的ViewModel的状态决定初始化哪些Dataset,确定需要初始化的每个Dataset都会调用的方法。

void initControls()

ViewModel初始化其中所有的不可视控件的方法。不可视控件包括下拉框、菜单、命令等等。其他的可视控件默认是不会在此处被初始化的,它们甚至还没有被创建。可视控件默认都是"懒创建"的,只有当将来JSP的Taglib真正引用到它或者用户使用ViewModel的getControl(id)方法获取它时才会被创建。

void initControl(Control control)

此方法会在initControls()的执行过程中以及JSP的执行过程中针对每一个创建出来的控件被激发。

void doLoadData()

当ViewModel开始为其中的Dataset装载数据时所调用的方法。只有在initDatasets()中已被初始化的Dataset才会在此处装载数据,因此调用该方法也是取决于ViewModel的当前状态的。

void doLoadData(ViewDataset dataset)

此方法会在doLoadData()的执行过程中针对每一个要处理的Dataset被激发。doLoadData()中需要处理的Dataset的数量决定了该方法被调用的次数。

void doUpdateData(ParameterSet parameters, ParameterSet outParameters)

默认的数据提交的处理方法。当Client端提交Dataset数据至Server端时,默认情况下在该方法中处理提交的Dataset数据。

表13-01
特别地,以上方法不是在所有情况都会被执行的,它与ViewModel的状态有关。

  • ViewModel.STATE_VIEW

在页面打开时的处理过程顺序
void init(int state)
void initDataset(ViewDataset dataset) 每个Dataset初始化时都会调用
void initDatasets()
void initControls()
void doLoadData()
void doLoadData(ViewDataset dataset) 加载数据,每个Dataset执行一次数据加载
void initControl(Control control) 初始化其中的不可见控件,每个不可见控件调用一次

  • ViewModel. STATE_SERVICE

执行Dataset动态数据刷新时(局部刷新)的过程顺序
void init(int state)
void initDatasets()
void initDataset(ViewDataset dataset) 仅初始化执行数据加载动作的Dataset。
void doLoadData()
void doLoadData(ViewDataset dataset)

  • ViewModel. STATE_UPDATING

执行数据提交时的过程顺序
void init(int state)
void initDatasets()
Void initDataset(ViewDataset dataset) 仅初始化被提交上来的Dataset。
void doUpdateData(ParameterSet parameters, ParameterSet outParameters)

ViewModel中的Dataset

ViewModel不会在服务器端缓存,即生命周期是Request范围。这意味着在服务器端,ViewModel中的Dataset的生命周期也是Request,同样不会在服务器端缓存,向浏览器端提供数据服务之后,Dataset数据集对象在服务器端会被销毁。
目前最新的Dorado6版本中,ViewModel默认提供7种Dataset供用户开发使用。