本文档描述了如何通过动态表单和Java插件在单据设计器中灵活展示数据。当前单据设计器的列表已不满足业务需求,需要更灵活的数据展示方式。实现方案包括新建单据和动态表单,通过Java插件向单据列表控件动态添加列并绑定数据。数据源通过QueryServiceHelper从数据库查询,插件需注册相关事件监听器来管理列和数据绑定。还提到了开发者可自由组装展示数据,但字段需与单据对应。此外,还提供了插件代码示例和异常处理方法。
如果文章对您有帮助,请为我点击一个朴实无华的赞^_^
1.需求背景
单据设计器中的列表已经无法满足业务需求了,要有一种更加灵活的方式展示数据。
移动表单,单据列表控件,java插件动态添加列表。
展示到前端的数据源使用QueryServiceHelper从一个数据库实体中查询出来。
单据和动态表单的元数据请查看附件,java插件代码请查看实现过程或者附件。
2.实现方案
(1)新建单据,增加几行单据数据(为第2步准备数据源)
(2)新建动态表单,动态表单中增加一个单据列表控件
(3)动态表单添加java插件
(4)Java插件中增加几个列,获取单据数据,返回给单据列表控件显示
3.实现过程
新增单据页面,如下,有一个单据头和一个单据体
新增2条单据数据
新增动态表单,拖入一个单据列表控件,用来展示单据数据
选择单据实体
展示的数据可以不用是这张单据里面的数据,可以由开发者随意组装,但是数据的字段要和单据里面的字段对应上。
例如我这单据的标识是:kdec_t_bill_1,准备展示在单据列表控件里面的数据,不必是kdec_t_bill_1里面的数据,但是数据的字段,一定要是kdec_t_bill_1中的字段。
开发者如何使用其他数据,展示在列表中,参考我的下一篇文章:
https://club.kdcloud.com/article/160703416723818496
动态表单注册插件:
编写插件时要注意几点:
(1)addCreateListColumnsListener事件负责新增列表控件的列,addBeforeBindDataListener负责组装数据
(2)新增列时,如果列是单据体的数据,设置不一样的FieldName和EntityName
(3)即便单据列表上不会展示单据的id或者不展示单据体的id,返回给列表控件的数据,也必须要有id字段。如果单据有单据体,也要有单据体的id。
以下是插件代码
package kd.demo.cosmic.form; import kd.bos.dataentity.entity.DynamicObjectCollection; import kd.bos.dataentity.entity.LocaleString; import kd.bos.form.events.BeforeBindDataEvent; import kd.bos.form.events.BeforeBindDataListener; import kd.bos.form.events.BeforeCreateListColumnsArgs; import kd.bos.form.events.BeforeCreateListDataProviderArgs; import kd.bos.form.plugin.AbstractFormPlugin; import kd.bos.list.BillList; import kd.bos.list.IListColumn; import kd.bos.list.ListColumn; import kd.bos.list.events.CreateListColumnsListener; import kd.bos.list.events.CreateListDataProviderListener; import kd.bos.mvc.list.ListDataProvider; import kd.bos.servicehelper.QueryServiceHelper; import java.util.List; public class DynamicAddListFormPlugin extends AbstractFormPlugin implements CreateListColumnsListener, BeforeBindDataListener { @Override public void initialize() { super.initialize(); BillList billList = this.getControl("kdec_billlistap"); // 注册监听 billList.addCreateListColumnsListener(this); billList.addBeforeBindDataListener(this); } @Override public void createListColumns(BeforeCreateListColumnsArgs arg0) { // 获取columns,增加几个列 List<IListColumn> columns = arg0.getListColumns(); ListColumn colUser1 = this.createListColumn("kdec_production", "水果产地", 0); columns.add(colUser1); ListColumn colUser2 = this.createListColumn("kdec_fruits", "水果名称", 1); // 单据体的字段,设置FieldName和EntityName和普通字段不一样 colUser2.setFieldName("kdec_entryentity.kdec_fruits"); colUser2.setEntityName("kdec_entryentity"); columns.add(colUser2); ListColumn colUser3 = this.createListColumn("billno", "编码", 2); columns.add(colUser3); } private ListColumn createListColumn(String key, String caption, int colIndex){ ListColumn col = new ListColumn(); col.setCaption(new LocaleString(caption)); col.setListFieldKey(key); col.setKey(key); col.setFieldName(key); col.setSeq(colIndex); col.setWidth(new LocaleString("8%")); return col; } @Override public void beforeBindData(BeforeBindDataEvent beforeBindDataEvent) { BillList billList = this.getControl("kdec_billlistap"); billList.addCreateListDataProviderListener(new CreateListDataProviderListener() { @Override public void createListDataProvider(BeforeCreateListDataProviderArgs args) { args.setListDataProvider(new BillListDataProvider()); } }); } // 内部类,为单据列表控件添加值 public class BillListDataProvider extends ListDataProvider { @Override public DynamicObjectCollection getData(int start, int limit) { // 如果对应的单据有单据体,并且单据体有多行数据 // 在查询时,必须查询多两个字段,单据id和单机体id:id, kdec_entryentity.id。 // 即时id不在列表中展示,也要查询出来,然后再把查询结果return DynamicObjectCollection data = QueryServiceHelper.query("kdec_t_bill_1", "billno, kdec_production, kdec_entryentity.kdec_fruits, id, kdec_entryentity.id", null); getQueryResult().setCollection(data); getQueryResult().setDataCount(data.size()); // 把列数据返回 return data; } } }
4.效果图
5.异常场景
(1)有伙伴反馈,实操之后出现以下异常:
分析之后,发现是ListCardView,即卡片视图,空指针异常
解决方法
1.隐藏卡片视图为卡片视图增加列即可:
2.createListColumns方法中,为卡片视图设置相同的列
动态表单展示单据列表.zip(6.82KB)