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供用户开发使用。