Dorado 5 : 1.2.4.DatasetDropDown(记录集下拉框) (RF2)

简述

记录集下拉框的列表项来自于Dataset对象,如下图:

图表 4 记录集下拉框
DatasetDropDown与ListDropDown的定义方式不同。与ListDropDown相比它不仅可以很简单的实现ListDropDown的功能,并且由于Dataset绑定功能,利用dataset的特性,可以使得DatasetDropDown具备更强和灵活的功能
例如:
列表项动态刷新;
下拉列表中可以显示更多的字段信息;
下拉选择可以实现对多个字段的取值和赋值工作;

使用

实现ListDropDown功能

利用DatasetDropDown实现ListDropDown的功能比较简单,首先需要专门为下拉列表项定义一个数据来源--Dataset对象,并指定两个字段labelField,valueField,它们与ListDropDown中DropDownItem对应的label,value信息是相同概念的.
例如ListDropDown使用一节中列举的dropdownResc,使用DatasetDropDown实现时,就需要定义一个dataset对象,这里命名为dsRescType,包含两个字段,结构如下:

<Dataset id="dsRescType" type="Custom">
<MasterLink />
<Fields>
<Field name="rescTypeCode" label="资源类型编码">
<Properties />
</Field>
<Field name="rescTypeLabel" label="资源类型标题">
<Properties />
</Field>
</Fields>
<Parameters />
<Properties />
</Dataset>

为了填充dsRescType的数据,可以给dsRescType添加一个监听器,实现其中的afterLoadData方法自定义导入数据:

public class DatasetRescTypeListener
extends AbstractDatasetListener {
public void afterLoadData(Dataset dataset)
throws Exception {
dataset.insertRecord();
dataset.setString("rescTypeCode", "url");
dataset.setString("rescTypeLabel", "页面");
dataset.insertRecord();
dataset.setString("rescTypeCode", "function");
dataset.setString("rescTypeLabel", "方法");
dataset.insertRecord();
dataset.setString("rescTypeCode", "control");
dataset.setString("rescTypeLabel", "组件");
}

}

在定义了dataset的相关信息之后,接着定义DatasetDropDown对象ddRescType,范例配置如下:

<Control
id="ddRescType"
type="DatasetDropDown"
dataset="dsRescType"
mapValue="true"
labelField="rescTypeLabel"
valueField="rescTypeCode" />

以上的范例设置中ddRescType的dataset属性设置为dsRescType,表示DropDown的列表项数据来自于dsRescType,而labelField与valueField属性分别为dsRescType中的字段rescTypeLabel, rescTypeCode,我们通过指定字段的方式告诉ddRescType读取dsRescType中rescTypeLabel的值作为label值,而rescTypeCode中的值作为value显示在下拉列表中。
mapValue的功能与ListDropDown中的mapValue相同。
说明:以上范例实现中dataset的数据获取采用了listener的方式,在实际应用中可以灵活处理,例如DBDataset一般都不需要定义listener,可以直接通过dataset的sql或则AutoSql属性定义实现,MarmotDataset一般就在dataProvider中实现....不同的dataset会有不同的实现方式。相关内容参考dataset使用部分。

实现下拉框中对列信息的展示

由于dataset对象可能会包含多个字段,而用户希望在下拉选项中同时看到多个字段的信息例如图表3,而不是ListDropDown中的DropDownItem这种非常简洁的信息。实现的方法如下:
如果dataset中包含了field1,....field10等10个字段用户指定希望下拉选项中看到fiedl1,field3,field9,field10.则我们可以在DatasetDropDown的visibleFields属性中指定:

<Control
id="dd1"
type="DatasetDropDown"
dataset="ds1"
visibleFields="field1,field3,field9,field10" />

注意这种实现方式不支持DatasetDropDown的mapValue处理机制,简单的说就是冲突。使用了1中的功能就不能使用2,3。

获取选中行的多个字段的信息

同2,既然下拉框中可以同时查看dataset的多个字段的信息,用户就希望能在选择一个下拉选项之后可以从中获得多个列的信息,如同是取出field1,field2,...,fieldn的信息。默认情况下,DatasetDropDown在选择之后都会出发onSelect方法,查看方法定义:

public Boolean onSelect(DropDown dropdown, Object selectedObject, TextEditor editor)

其中参数selectedObject为用户在下拉列表中选中的行所代表的dataset中的record记录。我们可以在这个事件中通过js脚本以及record对象获取下拉列表选中行各个列的详细信息,并加以进一步的处理。事件范例代码:

var record = selectedObject; //获取用户选中行代表的记录对象
var deptId = record.getValue("dept_id");//获取选中记录的部门编号信息
var deptName = record.getValue("dept_name");//获取选中记录的部门名称信息
var branchId = record.getValue("branch_id");//获取选中记录的分公司编号信息

//将信息保存到另一对象中,本例为另一个dataset对象dsAnother
dsAnother.setValue("field1", deptId);
dsAnother.setValue("field2", deptName);
dsAnother.setValue("field3", branchId);
...

return true;//执行系统默认动作

以上范例中利用selectedObject对象获取详细信息并保存到其他的对象中,在本例中使用另一个dataset实现保存。
对于以上的这个具体范例来说,最终效果是把selectedObject中的dept_id,dept_name,branch_id三个字段信息复制到dsAnother中的field1,field2,field3中。这种应用在实际开发中还是很常见的,为了更方便的实现该功能,DatasetDropDown提供了两个特殊的属性,readFields,writerFields。如上范例可以这么定义:

<Control
id="dd1"
type="DatasetDropDown"
dataset="ds1"
readFields="dept_id,dept_name,branch_id"
writeFields="field1,field2,field3" />

当系统读取到readFields,writerFields信息时会自动上面一段的js脚本动作。通过这种方式开发人员可以不用写脚本,而是通过配置方式实现字段与字段的值复制处理。

常用技巧

基本技巧参考ListDropDown的常用技巧

自定义beforeOpen事件:

在很多系统中,一个页面的同一个下拉框对象在整个页面的生命周期中可能需要显示不同的下拉列表项,通常情况下我们都可以通过beforeOpen事件加以控制,代码如下:
控制一(本地处理,不需要和服务器交互的):

var ds = dropdown.getDataset();
ds.insertRecord();
ds.setValue("dept_id", "D39");
ds.setValue("dept_name", "深圳分公司大客户服务部");
ds.setValue("branch_id", "D3");
ds.refreshCOntrols();

控制方法二(AJAX请求)

var ds = dropdown.getDataset();
ds.parameters().setValue("branch_id", "D3");//动态设置查询参数
ds.flushData();//使用XMLHttp技术将查询参数上传到服务器,并重新获取数据到客户端
ds.refreshControls();

beforeOpen函数还可用于控制是否允许下拉框打开,例如对于第二种控制方法中,通常branch_id的信息都来自于页面上其他对象,如果还没有branch_id信息我们就不允许用户打开新的下拉框选择,代码如下:

var branchId = dsAnother.getValue("branch_id");
if (branchId=="") return new AbortException("请先输入部门编号信息再选择!");

var ds = dropdown.getDataset();
ds.parameters().setValue("branch_id", "D3");//动态设置查询参数
ds.flushData();//使用XMLHttp技术将参数上传到服务器,并重新获取数据到客户端
ds.refreshControls();

自定义onSelect事件:

参考: 获取选中行的多个字段的信息

非常规技巧

如何根据其它字段中值的变化动态改变记录集下拉框中的内容

我们可在指定字段所属dataset对象的afterChange事件中

switch (field.getName()) {
case "field1":
dropdownDataset.parameters().setValue("param1", dataset.getValue("field1"));//dataset为当前被修改的记录集
dropdownDataset.flushData();//重新更新下拉框所绑定的dataset中的数据
break;
}

动态改变与DatasetDropDown绑定的Dataset

var sex = record.getValue("sex");
if(sex=="0"){
sexDropDown.setDataset(boyDataset);
}else{
sexDropDown.setDataset(girlDataset);
}

动态编程

在服务器段动态生成DatasetDropDown

protected void initControls() throws Exception {
super.initControls();//系统默认函数,注意保留
DatasetDropDown dropdown1= (DatasetDropDown)createControl("DatasetDropDown","dropdown1");
dropdown1.setDataset("dsDept");//设置绑定的dataset
dropdown1.setFixed(true);
dropdown1.setReadFields("dept_id,dept_name,branch_id");
dropdown1.setWriteFields("field1,field2,field3");
}

使用视图模型实现类提供的createControl方法创建DatasetDropDown对象,注意第一个参数用以指定组件的类型,第二个参数指定新建对象的id

在服务器端获得View(视图模型)中定义的DatasetDropDown,并动态它的属性

protected void initControls() throws Exception {
super.initControls();//系统默认函数,注意保留
DatasetDropDown dropdown1= (DatasetDropDown)getControl("dropdown1");
dropdown1.setDataset("dsDept");//设置绑定的dataset
dropdown1.setFixed(true);
dropdown1.setReadFields("dept_id,dept_name,branch_id");
dropdown1.setWriteFields("field1,field2,field3");
}

在上面的代码中可以看到通过实现类提供的getControl函数获得我们需要的组件对象,所需要的就是给它一个DatasetDropDown对象的id,注意开发时我们建议您直接在View的设计中添加一个空DatasetDropDown组件,这样我们就可以在initControls方法中通过getControl方法获得这个空的DatasetDropDown对象,并利用该对象提供的API进行各种设定和初始化的工作,如DatasetDropDown的setReadFields,setWriteFields方法。

主要属性说明

基本属性参考ListDropDown

属性

说明

Dataset

下拉框绑定的数据集

labelField

如果希望下拉框实现类似ListDropDown的自动数据映射功能,labelField就是设定被转换成label显示的字段名,与valueField配合使用

readFields

下拉选择后系统自动从下拉框绑定的dataset中要读取值的字段名,多个字段用逗号隔开,该属性与writeFields配合使用,用于实现多个字段同时赋值的功能

showColumnHeader

是否显示表格头

valueField

用于实现类似ListDropDown的自动数据映射功能,下拉框从绑定的编辑框中取出值,到绑定的dataset中查找与valueField指定字段相匹配的值,并根据labelField的设定将labelField的值显示在编辑框中

visibleFields

默认情况下下拉列表显示绑定dataset的所有的字段,如果想定制可以通过该属性指定要显示的字段,多个字段间用逗号隔开

writeFields

与readFields配合使用,用于指定下拉选择后系统自动从dataset中读取readFields中指定字段的值,并写入绑定下拉框的编辑框所绑定的dataset中writeFields指定的字段中去

主要事件说明

基本事件参考ListDropDown

事件

说明

public Boolean onSelect(DropDown dropdown, Object selectedObject, TextEditor editor)

当选择了下拉数据时触发
此事件的返回值用于通知系统是否要继续完成后续的为编辑框或数据集赋值的操作.返回true表示继续默认的赋值操作.
参数说明:
dropdown - 触发事件的下拉框对象
selectedObject - 在下拉框中被选中的记录对象
editor -打开此下拉框的编辑框对象

CSS说明

参考ListDropDown的css说明