Dataset Listener事件使用详解
下面对监听器类里面每个方法进行解析一下:
方法 | 说明 |
|---|---|
void onInit(Dataset dataset) | Dataset的初始化方法。此方法在Dataset.init中最后触发的,也就是说在Dataset根据view.xml被创建的时候才触发 |
boolean beforeCreateFields(Dataset dataset) | Dataset一般是通过本身的doLoad方法来创建字段和加载数据的,如设定了autoCreateFields为true或者在view.xml里没有设定fields,则触发该方法 |
void afterCreateFields(Dataset dataset) | 如果进入了beforeCreateFields方法处理完返回的值是true,那么Dataset将进入doLoad方法来创建字段和加载数据,处理完之后就触发该方法,也就是说如beforeCreateFields没被触发或者beforeCreateFields返回false都不会触发该方法 |
boolean beforeLoadData(Dataset dataset) | Dataset在页面初始化时设定autoLoadData为true或者通过ajax来加载数据的时候,在加载数据(doLoad)之前会触发该方法,如该方法返回true才进入doLoad加载数据 |
void afterLoadData(Dataset dataset) | Dataset在做完beforeLoadData和doLoad(不一定要触发doLoad)之后才触发的事件,如触发过beforeLoadData才会触发本方法 |
boolean beforeUpdateData(Dataset dataset) | 当Dataset执行update方法的时候触发,在更新数据(doUpdate)之前会触发该方法,如该方法返回true才进入doUpdate更新数据 |
void afterUpdateData(Dataset dataset) | Dataset在做完beforeUpdateData和doUpdate(不一定要触发doUpdate)之后才触发的事件 |
以上方法不是在所有情况都会被执行的。
我们根据上面表格对Dataset Listener里各种方法的说明,可以很清楚地知道每个方法的作用:
- onInit
该方法一般会处理一些Dataset的属性设置,比如你想在进入ViewModel的initDataset之前就修改Dataset在view.xml的配置信息。
- beforeLoadData
该方法一般是处理Dataset在加载数据之前改变Dataset为了取到数据而需要的属性,或者直接在这个方法里加载数据。
在本方法里改变Dataset的属性或者上下文来确定Dataset怎样取到数据,这里一般返回true。
在本方法里加载数据,而不需要Dataset的默认加载方式,这里一般返回false,最常用该方法的Dataset是CustomDataset。
- beforeCreateFields
这里一般会返回true或者false来决定Fields由本方法来创建还是让Dataset的doLoad方法来创建。
在本方法中对Dataset创建了一些Fields,不想让Dataset执行默认的创建Fields,则返回false;既想对Dataset创建了一些Fields,又想让Dataset执行默认的创建Fields,那则返回true。
- afterCreateFields
本方法在Dataset的doLoad做完之后触发的,所以一般不会使用本方法来处理Fields,除非你想在doLoad的时候需要的Fields和出现到页面时的Fields不同,或者在之前加载Fields在doLoad所需要的属性,在本方法里才加载Fields的显示属性。
- afterLoadData
本方法是在b、c、d完成直接触发的方法,本方法触发的条件是b) beforeLoadData必须触发,在c与d中间可能会执行Dataset的load方法来获取数据。
本方法一般是处理获取到数据之后来对结果操作,比如有些数据获取到Dataset之后才对Records做筛选才展现到页面,或者对Records做修改才显示到页面等等。
- beforeUpdateData
本方法是通过Dataset.update触发的,一般是Dataset封装了update的处理才进入处理。一般会在AutoSqlDataset和SqlDataset中用到,因为这些Dataset一般不需要我们通过UpdateCommand在ViewModel.java定义Method来提交数据。如你要通过UpdateCommand在ViewModel.java定义Method来提交数据又想触发本方法,请在UpdateCommand的Method方法中调用super.doUpdateData(parameters, outParameters);通过super.doUpdateData会执行Dataset.update,从而触发本方法。
该方法一般是处理Dataset在提交数据之前改变Dataset的记录集,或者直接在这个方法里提交数据。
在本方法里改变Dataset的记录集,这里一般返回true。
在本方法里提交数据,而不需要Dataset的默认提交方式,这里一般返回false
- afterUpdateData
触发原理跟f)一样。
本方法一般是处理提交数据之后来对结果操作,比如有些数据提交到Dataset之后才对Records做筛选才展现到页面,或者对Records做修改才显示到页面等等,最常见的是自动Id的获取。
Dataset Listener高级用法
我们在4.2.1中已经了解到Listener中大概分成3个不同地方触发的事件:一个是onInit;一个是beforeLoadData、beforeCreateFields、afterCreateFields、afterLoadData;另一个是beforeUpdateData、afterUpdateData。
onInit是在ViewModel根据view.xml创建Dataset的时候触发的,但又在initDataset之前,所以Listener的onInit事件的触发只能在view.xml配置Dataset的Listener,想在java代码中动态添加Listener就相对不可能了。
beforeLoadData、beforeCreateFields、afterCreateFields、afterLoadData是在Dataset获取数据的时候触发的,所以在view.xml配置Dataset的Listener或者在Dataset执行Load之前添加都可以。
beforeUpdateData、afterUpdateData是在Dataset提交数据的时候触发的,所以在view.xml配置Dataset的Listener或者在Dataset执行update之前添加都可以。
动态给Dataset添加Listener
根据上面的说明,可以清楚地知道想在Listener中处理哪些事件,就在相应的触发事件前给Dataset添加Listener。比较常用的是在ViewModel的initDataset中对Dataset添加Listener。
protected void initDataset(ViewDataset dataset) throws Exception {
// TODO Auto-generated method stub
super.initDataset(dataset);
if ("datasetCustom".equals(dataset.getId())) {
DatasetListener datasetListener = new CustomDatasetListener();
dataset.addDatasetListener(datasetListener);
}
}
代码 4.1:ViewModel的initDataset中对Dataset添加Listener
给Dataset添加多个Listener
Dataset中Listener是可以设置多个的,所以其实Dataset是执行Listeners。Listeners是一个堆栈,当Dataset执行Listeners事件的时候,Dataset会对每个Listener的事件都处理一次,直到处理完所有Listeners。
当多个Listener组成Dataset的Listeners时,事件中没有返回值的是每个Listener都执行的,有返回值时当有一个返回值是false的时候就终止了该事件往下的执行,后面将要执行的Listener该事件将不会执行。
下面的例子当中,view.xml中已经对Dataset配置了一个Listener(通过";"还可以配置多个Listeners),在ViewModel的initDataset中还动态地添加一个Listener:

图 4.1:view.xml对Dataset配置一个Listener
public class Sample2_1ViewModel extends DefaultViewModel {
public void init(int arg0) throws Exception {
super.init(arg0);
}
protected void initDataset(ViewDataset dataset) throws Exception {
super.initDataset(dataset);
if ("datasetCustom".equals(dataset.getId())) {
DatasetListener datasetListener = new CustomDatasetListener2();
dataset.addDatasetListener(datasetListener);
}
}
}
代码 4.2:ViewModel的initDataset中对Dataset增加Listener
package com.bstek.dorado5.docent.chapter2;
import com.bstek.dorado.data.AbstractDatasetListener;
import com.bstek.dorado.data.Dataset;
public class CustomDatasetListener extends AbstractDatasetListener {
public void onInit(Dataset dataset) throws Exception {
super.onInit(dataset);
}
public void afterCreateFields(Dataset dataset) throws Exception {
super.afterCreateFields(dataset);
}
public void afterLoadData(Dataset dataset) throws Exception {
super.afterLoadData(dataset);
}
public void afterUpdateData(Dataset dataset) throws Exception {
super.afterUpdateData(dataset);
}
public boolean beforeCreateFields(Dataset dataset) throws Exception {
return super.beforeCreateFields(dataset); // true
}
public boolean beforeLoadData(Dataset dataset) throws Exception {
return true;
}
public boolean beforeUpdateData(Dataset dataset) throws Exception {
return super.beforeUpdateData(dataset); // true
}
}
代码 4.3:CustomDatasetListener代码
package com.bstek.dorado5.docent.chapter2;
import com.bstek.dorado.data.AbstractDatasetListener;
import com.bstek.dorado.data.Dataset;
import com.bstek.dorado.data.ParameterSet;
import com.bstek.dorado.data.Record;
import com.bstek.dorado.utils.StringHelper;
public class CustomDatasetListener2 extends AbstractDatasetListener {
public void onInit(Dataset dataset) throws Exception {
super.onInit(dataset);
}
public void afterCreateFields(Dataset dataset) throws Exception {
super.afterCreateFields(dataset);
}
public void afterLoadData(Dataset dataset) throws Exception {
super.afterLoadData(dataset);
}
public void afterUpdateData(Dataset dataset) throws Exception {
super.afterUpdateData(dataset);
}
public boolean beforeCreateFields(Dataset dataset) throws Exception {
return super.beforeCreateFields(dataset);
}
public boolean beforeLoadData(Dataset dataset) throws Exception {
ParameterSet parameters = dataset.parameters();
String EMPLOYEE_ID = parameters.getString("EMPLOYEE_ID");
String DEPT_ID = parameters.getString("DEPT_ID");
// 模拟查询数据
if (StringHelper.isNotEmpty(EMPLOYEE_ID)
|| StringHelper.isNotEmpty(DEPT_ID)) {
Record record = dataset.insertRecord();
record.setString("EMPLOYEE_ID", EMPLOYEE_ID);
record.setString("DEPT_ID", DEPT_ID);
} else {
Record record = dataset.insertRecord();
record.setString("EMPLOYEE_ID", "Default");
record.setString("DEPT_ID", "Default");
record = dataset.insertRecord();
record.setString("EMPLOYEE_ID", "Default2");
record.setString("DEPT_ID", "Default2");
}
return false;
}
public boolean beforeUpdateData(Dataset dataset) throws Exception {
return super.beforeUpdateData(dataset);
}
}
代码 4.4:CustomDatasetListener代码
通过上面的代码可以看见ViewModel的时候,通过一个配置和一个动态加载使datasetCustom添加了两个Listener,当Dataset执行Listeners事件的时候,会把所有的Listeners同一事件不同的顺序执行,比如上面例子当中执行Listener的onInit事件,就会先执行CustomDatasetListener的onInit事件,然后再执行CustomDatasetListene2r的onInit事件,当两个都执行完之后,Listener的onInit事件才是正在的执行完毕。当事件中有返回值的时候,Listener的执行会根据返回值来确定要不要继续执行不同Listener的同一事件,比如上面例子中的beforeLoadData事件,Dataset Listener先执行CustomDatasetListener的beforeLoadData事件,因为该事件中返回true,所以继续往下执行剩下的Listener beforeLoadData事件,因此再执行CustomDatasetListener2的beforeLoadData事件。由于CustomDatasetListener2的beforeLoadData事件返回false,所以总的beforeLoadData事件返回false,这个返回值会影响到后面Dataset的LoadData的执行。我们再把CustomDatasetListener和CustomDatasetListener2的顺序换一下,也就是说把他们添加在Dataset的顺序换一下,那么先执行CustomDatasetListener2的beforeLoadData事件,这个时候就已经返回false,那么下面CustomDatasetListener的beforeLoadData事件就不会再执行,总的beforeLoadData事件也返回false。