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。