Aurora开发备忘
Aurora开发备忘
- Aurora开发备忘
- 1 screen文件
- 1.1 字段只读
- 1.2 lov 弹出式选择框,带查询按钮和查询条件
- 1.3 通过 js手动执行dataSet中的查询
- 1.4 在js中获取系统描述
- 1.5 自定义数据校验
- 1.6 通过Aurora发起ajax请求
- 1.7 js中设置必输校验
- 1.8 界面的field添加renderer
- 1.9 prompt 属性添加
- 1.10 js 添加ds数据
- 1.11数据导出excel
- 1.12 界面弹窗参数传递
- 1.13 comboBox对应值列表的书写方式
- 1.14 grid合并单元格写法
- 1.15 Aurora中判断组件是否存在
- 2 lov书写格式
- 3 bm技巧
- 3.1 bm传入数组参数
- 3.2 往sql中拼接sql语句段
Aurora开发备忘
Aurora框架主要编辑的文件包括bm数据库操作文件(类比mapper文件)、oracle数据库包pkg文件(类比java文件)、screen界面展示文件(类比jsp文件)。学习中,持续更新…
1 screen文件
一个screen文件的基本的格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<a:screen xmlns:a="http://www.aurora-framework.org/application" trace="true"><a:init-procedure><!--界面显示前,服务器端执行查询,结果放在rootPath里面,界面可通过/model/acc_entity路径取值--><a:model-query fetchAll="true" model="hec_util.gld_accounting_entities_vl_lov" rootPath="acc_entity"/></a:init-procedure><a:view><a:link id="CON2000_req_detail_show_link" url="${/request/@context_path}/modules/pur/PUR7010/pur_requisition_view_main.screen"/><script><![CDATA[//此处是写前端js脚本的位置,语法遵循Ext框架以及,Aurora对Ext的扩展]]></script><a:dataSets><!--dataSets下面配置界面上要用到的数据源,一般有3种来源:指向某个bm文件、前文提到”init-procedure“查询结果、系统描述”lookupCode“(数据来源是类似项目国际化的配置文件,不过这里的国际化数据是存到数据库里面的)--><a:dataSet id="CON2000_accEntityDs"><a:datas dataSource="/model/acc_entity"/></a:dataSet><a:dataSet id="CON2000_yes_no_ds" lookupCode="YES_NO"/><a:dataSet id="CON2000_typeChoiceAccEntityDs" loadData="true" model="hec_util.gld_accounting_entities_vl_lov"/></a:dataSets><a:screenTopToolbar><!--界面按钮:增删查改、导出、打印等--><a:gridButton bind="CON2000_grid" type="save"/></a:screenTopToolbar><!--可提交的表单--><!-- bindTarget:(官网注释:需要绑定的DataSet的ID)组件展示数据的数据来源ds,会作为查询条件; resultTarget:(官网注释:映射的DataSet)表单查询结果映射到的目标结果集,其实也是一个ds,查询结果刷新这个ds的值--><a:queryForm bindTarget="CON2000_con_contract_query_ds" resultTarget="CON2000_con_contract_query_result_ds"><!--表单元素(查询条件)--><a:formToolBar><a:textField name="partner_name" bindTarget="CON2000_con_contract_query_ds"/></a:formToolBar><!--扩展元素(查询条件)--><a:formBody column="4"><a:multiComboBox name="contract_status_name" bindTarget="CON2000_con_contract_query_ds"/></a:formBody></a:queryForm><!--动态表格--><a:grid id="CON2000_grid" bindTarget="CON2000_con_contract_query_result_ds" marginHeight="115" marginWidth="3" navBar="true"><!--底部表格工具--><a:toolBar><a:button type="delete"/></a:toolBar><!-- 表格列 --><a:columns><a:column name="contract_number" align="center" renderer="CON2000_conRenderer" sortable="true" width="120"/><a:column name="stamp_duty_type_name" align="center" editorFunction="CON2000_stampDutyTypeEditorFunc" width="120"/><a:columns><!--为表格中可编辑的列,增加编辑组件--><a:editors><a:textArea id="CON2000_ta"/></a:editors></a:grid></a:view>
</a:screen>
更多界面标签组件描述可参见官方文档:Aurora官方tag文档
1.1 字段只读
为字段标签加上readOnly="true"属性。可以加到dataSet里面,也可直接加到界面组件上。如果界面组件是column,默认是不可编辑的,readOnly="true"可以加到column的editor上。
加到数据源dataSet上:
<a:dataSet id="SEL0010_receiptHeaderDs" submitUrl="${/request/@context_path}/modules/sel/SEL0010/sel_negotiate_report_save.svc"><a:datas dataSource="/model/headerInfo"/><a:fields><a:field name="sel_type_desc" prompt="BGT_BALANCE_RUNNING_PARAMETERS.DOCUMENT_TYPE" readOnly="true"/></a:fields></a:dataSet>
界面组件是表单form,加到界面组件上:
<a:screenBody><a:form id="SEL0010_receiptMainForm" column="1" marginWidth="0" title="${/model/headerInfo/record/@item_type_name}"><a:box column="4" style="width:100%"><a:textField name="sel_type_desc" bindTarget="SEL0010_receiptHeaderDs" readOnly="true"/></a:box></a:form></a:screenBody>
界面组件是表格grid的列,加到editor上。editor相当于是在列上定义一个表单组件,用于编辑单元格。
在js中处理只读:
var h_info = $au('header_info_ds').getAt(0);
h_info.getMeta().getField('description').setReadOnly(false);
//似乎也可以这样
h_info.getField('description').setReadOnly(false);
1.2 lov 弹出式选择框,带查询按钮和查询条件
动态设置查询条件
<style><![CDATA[.reqnumberlov {color: #005a78;text-decoration: none;cursor: pointer;}.reqnumberlov:hover {color: #ff9900;text-decoration: none;}
]]></style>
...
...
<!--className属性同html标签添加class样式一样-->
<a:lov name="source_contract_number" id="source_contract_number_lov" bindTarget="CON1050_contract_header_maintain_ds" className="reqnumberlov" prompt="CON.MAIN_CONTRACT"><a:events><a:event name="focus" handler="source_contract_number_func2"/></a:events>
</a:lov>
function source_contract_number_func2(){var record = $au('CON1050_contract_header_maintain_ds').getAt(0);record.getField('source_contract_number').setLovPara('acc_entity_id', record.get('acc_entity_id'));if('${/model/header_info/record/@contract_attribute}'=='MATERIAL'){//修改查询用的bmrecord.getField('source_contract_number').setLovService('cont.CON1050.con_contract_source_headers_infor_lov2');//设置bm中的查询参数record.getField('source_contract_number').setLovPara('partner_id', record.get('partner_id'));//设置lov弹出框的标题record.getField('source_contract_number').setTitle('主合同编号'); }
}
注意:此处lov组件是位于表单控件内的,即xxx_ds作为一个form的数据源,一个field对应的值只有一个。还有种情况是,xxx_ds 作为一个grid的数据源,一个field对应一个grid的列,field对应的值是一个集合,lov嵌入到这一列的每一行的column中。那么,通过$au{‘xxx_ds’).getAt(0),只能获取到第一行的数据。如何获取当前行的其它列的值作为查询条件呢?
1、通过查阅Aurora-all.js 。上面handler方法中可以加一个入参,参数是当前组件Component即当前lov。我们可以从当前组件中获取到当前行的record。也可以通过当前组件更新lov入参。
界面代码:
<a:grid id="doctype_relation_grid" bindtarget="doctype_relation_result_ds"><a:columns> ...<a:column name="hec_doc_code" align="center" editor="hec_doc_code_lov"/>...</a:columns><a:editors><a:lov id="hec_doc_code_lov"><a:events><a:event name="focus" handler="ACP3101_onDocTypeFocusFun"/></a:events></a:lov></a:editors></a:grid>
js代码
function ACP3101_onDocTypeFocusFun(cmp){var hec_doc_type_code=cmp.record.get('hec_doc_type_code');if(hec_doc_type_code){cmp.para.hec_doc_category=hec_doc_type_code;}}
2、将focus事件改成cellclick事件,加到grid上。在handler中通过行列的判断,cellclick事件的入参带record(行数据)、row(行)等。拿到了当前行的record,就可以按1.2中最开始的方法处理了。
<a:grid id="CSH5010_csh_payment_requisition_grid" autoAdjustHeight="true" bindTarget="CSH5010_pay_req_create_line_ds" gridskin="gridskin" marginHeight="350" marginWidth="12" navBar="true" style="margin-top:-4px;"><a:columns></a:columns><a:editors>...</a:editors><a:events><a:event name="cellclick" handler="CSH5010_onPaymentReqLineCellClickFun"/></a:events>
</a:grid>
通过js除了可以动态处理lov的查询语句、查询参数、查询弹出框的标题等。还可以设置查询结果,字段的对应关系。
function CSH5010_onPaymentReqLineCellClickFun(grid, row, name, record) {//这里是在grid的cellclick事件方法中,入参带有当前行的record数据var payment_req_type_code = '${/model/header_info/record/@payment_req_type_code}';if (name == 'acc_entity_name' && payment_req_type_code == 'WCSH0020'){var account_mapping = [{from: 'acc_entity_id',to: 'acc_entity_id'}, {from: 'acc_entity_code',to: 'acc_entity_code'},...{from: 'gl_account_name',to: 'gl_account_name'}]; record.getField('acc_entity_name').setLovService('hec_util.gld_acc_entities_payee_vl_lov');record.getField('acc_entity_name').setLovPara('company_id', record.get('company_id'));//设置查询结果字段和field字段的映射关系record.getField('acc_entity_name').setMapping(account_mapping); }
}
1.3 通过 js手动执行dataSet中的查询
通过js手动执行一个dataSet的查询,此操作方便手动改变查询条件。引用此数据源的界面也会随查询结果动态变化。
$au('SEL0010_attach_record_ds').setQueryParameter('sel_negotiate_type_id', record.get('sel_negotiate_type_id'));
$au('SEL0010_attach_record_ds').setQueryParameter('enable_flag', 'Y');
$au('SEL0010_attach_record_ds').query();
关于dataSet的方法,可参见Aurora官方文档:Aurora官方js文档 当然有时候他们官网会挂。。。那就直接翻源码吧:Aurora-all.js
1.4 在js中获取系统描述
系统描述,是系统框架集成的,类似国际化配置,也可以当作字典。通过:${l:key} key为系统描述中的描述字段
if (typeId && record.get('requirement_source_type') != 'MANUAL') {return '<a href="javascript:CON1010_assign_req_typeInfo(' + typeId + ')">${l:CON_MO_CONTRACT_TYPES_VL.ASSIGN_REQ_TYPE}</a>';}
1.5 自定义数据校验
主要参考校验函数的写法
组件上加validator属性,值是校验函数的名字
<a:dataSet id="SEL0010_assets_discard_line_ds" autoQuery="true" bindName="assets_discard_lines" bindTarget="SEL0010_receiptHeaderDs" model="sel.SEL0010.sel_assets_discard_lines" queryUrl="${/request/@context_path}/autocrud/sel.SEL0010.sel_assets_discard_lines/query?sel_negotiate_header_id=${/model/headerInfo/record/@sel_negotiate_header_id}" selectable="true" submitUrl="${/request/@context_path}/autocrud/sel.SEL0010.sel_assets_discard_lines/batch_update"><a:fields><a:field name="assets_number" lovService="sel.SEL0010.sel_asset_number_no_ref_query_lov" required="true" title="资产编号选择" validator="numsRepeatValidator"/></a:fields></a:dataSet>
在js里面增加校验函数,返回字符串,会提示到界面,返回true会校验成功,校验函数会在控件失去焦点和表单提交时触发。如果校验失败(返回非true),失去焦点触发->悬停提示框提示。表单提交触发->弹框提示,表单提交会被终止。
function numsRepeatValidator(record, name, value){var records = $au('SEL0010_assets_discard_line_ds').getAll();if(records.length>1){for(var i=0;i<records.length;i++){if(records[i].get('assets_number')==value&&records[i].get('line_number')!=record.get('line_number')){return 'xxxx有重复';}}}return true;
}
1.6 通过Aurora发起ajax请求
首先在顶部添加链接地址
<a:link id="CON1050_contrac_donate_sum_amount" model="cont.CON1050.sel_donate_req_header_lov" modelaction="query"/>
在js中编写调用方法
function amountValidator(record, name, value){Aurora.request({url: $au('CON1050_contrac_donate_sum_amount').getUrl(),sync:true,para: {relation_donate_num: relation_donate_num,employee_id:record.get('employee_id')},success: function (resp) {if (resp && resp.result && resp.result.record) {var amount=resp.result.record.donate_sum_amount;if(amount<value){debugger;return '原币金额必须小于等于“关联捐赠申请”的单据头总金额!';}}}return true;}
注意,我在validator里面加的ajax,即使此处加了sync:true 。也会异步返回true。 导致校验失败。
1.7 js中设置必输校验
js中使用setRequired(true)需要放在handler里面。如果放到Aurora.onReady()里面,可能不会生效哦。
<a:dataSets><a:dataSet id="CON1050_contract_header_maintain_ds" ><a:fields><a:field name="description" prompt="CON_CONTRACT_HEADERS.DESCRIPTION"/></a:fields><a:events><a:event name="load" handler="CON1050_loadHandler"/></a:events></a:dataSet></a:dataSets>
function CON1050_onMaintainReady() {var record = $au('CON1050_contract_header_maintain_ds').getAt(0);record.getMeta().getField('description').setRequired(true);}Aurora.onReady(CON1050_onMaintainReady);
function CON1050_loadHandler() { var record = $au('CON1050_contract_header_maintain_ds').getAt(0);record.getMeta().getField('description').setRequired(true);}
1.8 界面的field添加renderer
在<a:form>内的表单元素中增加 renderer属性。
<a:view><a:form id="CON1050_view_form_place_id0" column="1" title="CON_CONTRACT_HEADERS_APPLY_INFOR"><a:formToolbar><!--表单工具按钮之类的-->...</a:formToolbar><!--增加一个box标签,方便排版表单元素排版,当然也可以增加多个box--><a:box column="4" id="jq_resort_box_h" labelWidth="115" style="width:100%"><a:textField name="document_desc" bindTarget="CON1050_contract_header_maintain_ds"/>...<!--当某个表单元素需要通过条件判断,是否存在时,可以在这里增加<a:placeHolder>标签,相当于一个预留位。在后面的config标签里面来判断此处该渲染成什么--><a:placeHolder id="CON1050_purchaseColumns"/></a:box></a:form></a:view><a:view-config><c:create-config targetId="CON1050_purchaseColumns"><!--这里的/model/.../record/@...是固定写法。header_info是后台返回给前端的对象的名字,@contract_attribute是取对象里面的contract_attribute字段的值--><p:switch test="/model/header_info/record/@contract_attribute"><p:case value="PURCHASE"><c:process-config><!--此处增加了renderer--><a:numberField name="wired_ratio" allowDecimals="false" bindTarget="CON1050_contract_header_maintain_ds" max="100" min="0" renderer="CON1050_wired_ratio"/></c:process-config></p:case><!--这个case没有加条件,表示其它--><p:case><c:process-config><a:comboBox name="acc_entity_name" bindTarget="CON1050_contract_header_maintain_ds"/></c:process-config></p:case></p:switch></c:create-config></a:view-config>
1.9 prompt 属性添加
prompt 属性,①可以加到<a:field>标签上,②也可以加到具体组件,如<a:textField>上。方式①影响界面显示和缓存中的prompt值,方式②只影响界面显示。所以,如果要校验该field。因为表单校验失败时,提示框的消息是取自缓存中的prompt,所以需要将prompt加到<a:field>上。综上,就统一加<a:field>上吧!
1.10 js 添加ds数据
关键词 create 。create后ds绑定的界面(通常是表格)会联动增加行。
js中的写法:
let data = {};data.seq_number=10;data.employee_name=cur.get('employee_name');...data.position_desc=cur.get('position_desc');$au('group_ref_emp_result_ds').create(data);
标签中的写法:
<a:dataSet id="group_ref_emp_result_ds" autoQuery="true" model="wfl.WFL4100...." queryUrl="${/request/@context_path}/autocrud/.../query" queryDataSet="..." selectable="true"><a:fields><a:field name="seq_number" prompt="..." required="true" validator="..."/></a:fields>...
</a:dataSet>
另外,判断一行数据是否是新建:isNew属性。
function editfunc(record, name) {return record.isNew ? 'WFL4100_approver_group_code_tf' : '';//保存后不运行修改}
1.11数据导出excel
1、一般导出,导出某个grid内的数据
添加导出按钮
<a:screenTopToolbar><!-- export_grid是导出表格的id --><a:gridButton bind="export_grid" type="excel" text="导出查询结果"/>
</a:screenTopToolbar>
...
<!-- 是将query_result_ds中查询出来的数据导出 -->
<a:grid id="export_grid" bindTarget="query_result_ds" ...>
...
</a:grid>
2、任意导出,导出任意查询结果集。
通过翻阅Aurora-all.js代码。可以发现,导出excel实际是调用的的$A.doExport方法
//Aurora-all.js
$A.doExport=function(dataset,cols,mergeCols,type,separator,filename,generate_state,param){...
}
...
其中要传入好几个参数。从方法内容不难看出,dataset是查询结果数据集,cols是导出的字段名和字段的对应关系。最后一个参数是查询参数数据集。从param的使用可以看出param传入的是一个json。其它参数可以暂时置空,不重要。
首先要确定导出哪些列,cols是一个固定格式的json。然后确定数据集和参数。
function export_detail(){//name字段填query_result_ds中的field的name属性。prompt填导出后的列名var cols=[{"prompt": "单据号","width": 100,"name": "exp_report_number","align": "center"},...{"prompt": "单据名称","width": 100,"name": "exp_report_type_name","align": "center"}];var r=$au('query_result_ds');//需要导出的数据集var params=$au('query_ds').getAt(0).data||{};//查询参数数据集转成json格式$A.doExport(r,cols,undefined,undefined,undefined,undefined,undefined,params);
}
在界面中添加按钮,绑定按钮点击事件。
<a:screenTopToolbar><a:gridButton text="导出查询结果明细" click="export_detail"/>
</a:screenTopToolbar>
1.12 界面弹窗参数传递
1、参数如果写在url后面:
var url='.../b.screen?enable_flag=Y&header_id=1...';
在b.screen中取值enable_flag、header_id等
//b.screen
var to_url='${/parameter/@enable_flag}';
var to_header_id='${/parameter/@header_id}';
2、如果参数写到para 里面:
Aurora.request({url: '.../b.screen',sync:true,para: {enable_flag: 'Y',header_id:1,...},...});
在b.screen中取值enable_flag、header_id等
//b.screen
var to_url='${@enable_flag}';
var to_header_id='${@header_id}';
此处取值方式有待确认
1.13 comboBox对应值列表的书写方式
首先界面需要一个<a:comboBox>标签
<a:dataSets><!-- 自定义值列表的数据源 --><a:dataSet id="FND4000_progress_status_ds"><a:datas><!--status_name、status_code可以自定义--><a:record status_name="全部" status_code=""/><a:record status_name="提交之后的单据" status_code="AFTER_SUBMIT"/><a:record status_name="提交之前的单据" status_code="BEFORE_SUBMIT"/></a:datas></a:dataSet><!--表单的数据源 --><a:dataSet id="query_ds"><a:field name="progress_status"/><a:field name="progress_status_desc" displayField="status_name" options="FND4000_progress_status_ds" prompt="单据状态" returnField="progress_status" valueField="status_code"/>...</a:dataSet>
</a:dataSets>
<!-- 这是一个作为查询条件的表单控件,查询结果将为grid提供数据 -->
<a:queryForm bindTarget="query_ds" ...><a:formToolBar>...</a:formToolBar><a:formBody column="3"><a:comboBox name="progress_status_desc"/>...</a:formBody>
</a:queryForm>
1.14 grid合并单元格写法
<a:grid id="query_result_ds" bindTarget="xxx"><a:columns><a:column name="acc_entity_name" align="center" width="120"/>...<a:column name="actual_line" prompt="xxx" width="660"><a:column name="jan_actual" align="center" width="50"/>....<a:column name="nov_actual" align="center" width="50"/><a:column name="dece_actual" align="center" width="50"/></a:column></a:columns>
</a:grid>
1.15 Aurora中判断组件是否存在
错误的方式:
//通过$au取值,如果不存在,直接就报错。
if($au('xxx_lov')){...
}
正确的处理方式:
//未验证过这种方式
if ($A.CmpManager.get('CON1050_expRelNumberLov')) {...
}
//验证有效的方式:应该和上面这种等效的,及$A 和 Aurora 等效
var signDs=Aurora.CmpManager.get('con_sigin_lines_ds');
if(signDs){}
2 lov书写格式
lov我的理解是,Aurora框架实现的一个弹出式选择框。涉及弹出框界面组件和数据查询bm。我们要实现自己的lov可以有两种方式,
1、使用系统自带的lov组件。我们只需要加查询bm就可以了。省去了写lov界面。
界面上写法:
<!--需要添加自定义的lov.bm,通过lovService属性指定--><a:field name="..." lovService="hec_util...._lov?dimension_id=${@dimension_id}&company_level=${@company_level}" ><a:mapping><a:map from="..._name" to=".._name}"/><a:map from="..._id" to=".._id"/></a:mapping></a:field>
bm写法。此bm与普通bm稍有不同。增加了一些属性。
<?xml version="1.0" encoding="UTF-8"?>
<bm:model xmlns:f="aurora.database.features" xmlns:bm="http://www.aurora-framework.org/schema/bm"><bm:operations><bm:operation name="query"><bm:query-sql><![CDATA[SELECTv.*FROM(--sql语句....) v #WHERE_CLAUSE#]]></bm:query-sql></bm:operation></bm:operations><bm:query-fields><bm:query-field name="tax_type_code" queryExpression="v.tax_type_code like '%' || ${@tax_type_code} || '%'"/><bm:query-field name="tax_type_name" queryExpression="v.tax_type_name like '%' || ${@tax_type_name} || '%'"/></bm:query-fields><bm:fields><bm:field name="tax_type_id"/><bm:field name="tax_type_code" forDisplay="true" forQuery="true" prompt="VAT_INVOICE_TAX_RATE_TYPES.TAX_RATE_TYPE_CODE"/><bm:field name="tax_type_name" forDisplay="true" forQuery="true" prompt="VAT_INVOICE_LINES.TAX_RATE"/><bm:field name="tax_type_rate"/></bm:fields><bm:data-filters><bm:data-filter name="query" expression="v.tax_type_id not in (select vv.tax_type_id from vat_invoice_rate_assign vv where vv.invoice_category_id = ${@invoice_category_id})"/></bm:data-filters>
</bm:model>
2、第二种方式是自定义弹出框的界面。写一个screen界面。添加界面需要的查询bm
<!--需要添加自定义的screen,通过lovUrl属性指定-->
<a:field name="default_object_code" lovGridHeight="320" lovHeight="460" lovUrl="${/request/@context_path}/modules/exp/EXP4020/..._lov.screen?mag_org_id=${/parameter/@mag_org_id}" lovWidth="500"><a:mapping><a:map from="code" to="default_object_code"/><a:map from="description" to="default_object_desc"/><a:map from="id" to="default_mo_object_id"/></a:mapping></a:field>
下面是js的写法
//这里material_description是一个lov组件(单选)...record.getField('material_description').setLovUrl('${/request/@context_path}/modules/fnd/FND8030/fnd_computer_choose_lov.screen');record.getField('material_description').setLovPara('pur_type_code', pur_type_code);record.getField('material_description').setLovPara('fnd_computer_info_id', fnd_computer_info_id);record.getField('material_description').setLovWidth('1300');record.getField('material_description').setLovHeight('550');record.getField('material_description').setTitle('xx信息');var mapping = [{from: 'fnd_computer_info_id',to: 'fnd_computer_info_id'}, {from: 'name_model',to: 'material_description'}, {from: 'amount',to: 'business_price'}];record.getField('material_description').setMapping(mapping);...
在fnd_computer_choose_lov.screen页面里面,加一个行双击事件:FND8030_dblClick,在函数里面提交目标行数据,固定的写法。record里面字段值就会按mapping传到父页面对应的字段上。
<?xml version="1.0" encoding="UTF-8"?>
<a:screen xmlns:a="http://www.aurora-framework.org/application"><a:init-procedure>...</a:init-procedure><a:view><script><![CDATA[function FND8030_dblClick(grid,record,row){$au('${/parameter/@lovid}').commit(record);}...]]></script><a:dataSets><a:dataSet id="FND8030_chooseComputerDs"><a:fields><a:field name="choosed_seq_number" defaultValue="${/model/choosed_computer/record/@seq_number}"/>...</a:fields></a:dataSet><a:dataSet id="FND8030_chooseComputerResultDs" autoQuery="true" model="fnd.FND8030.fnd_computer_info_query" queryUrl="${/request/@context_path}/autocrud/fnd.FND8030.fnd_computer_info_query/query?pur_type_code=${/parameter/@pur_type_code}" queryDataSet="FND8030_chooseComputerDs"/></a:dataSets><a:screenBody><span><a:queryForm bindTarget="FND8030_chooseComputerDs" resultTarget="FND8030_chooseComputerResultDs" style="width:100%;border:none"><a:formToolBar labelWidth="100"><a:textField name="product_model" bindTarget="FND8030_chooseComputerDs"/>...</a:formToolBar></a:queryForm></span><a:grid bindTarget="FND8030_chooseComputerResultDs" height="450" navBar="true" width="1280"><a:columns><a:column name="seq_number" align="center" width="50"/>...</a:columns><a:events><a:event name="dblclick" handler="FND8030_dblClick"/></a:events></a:grid></a:screenBody></a:view>
</a:screen>
3 bm技巧
3.1 bm传入数组参数
bm是没法输入数组作为查询条件的。通过带分隔符的字符串来转换。如下。
<bm:query-sql><![CDATA[SELECTh.req_number,h.req_header_id,pur_util_pkg.get_mo_req_type_name(p_mo_req_type_id => h.mo_req_type_id) req_type_name,hec_util_pkg.get_employee_name(p_employee_id => h.employee_id) employee_name,h.description,TO_CHAR(h.requisition_date, 'YYYY-MM-DD') requisition_date,sys_code_pkg.get_sys_code_value_name(p_code => 'PUR_PR_STATUS', p_code_value => h.status) status_nameFROMpur_requisition_headers hWHEREh.req_number IN ((SELECT*FROMTABLE(hec_util_pkg.parse_multi_param(p_parameter_value => ${@pur_req_num}, p_split_chars => ';'))))]]></bm:query-sql>
存储过程parse_multi_param的写法:
/* =============================================* FUNCTION* NAME : PARSE_MULTI_PARAM* DESCRIPTION: MulitComboBox 查询条件转换* ARGUMENT: ** RETURN:* character_table -- 参数表* HISTORY:* 1.00 11/1/2017 12:09:23 PM Tagin* Creation Description* 1.01 yyyy/mm/dd Author Name* Changes Description* =============================================*/FUNCTION parse_multi_param(p_parameter_value IN VARCHAR2,p_split_chars IN VARCHAR2 DEFAULT NULL)RETURN character_tablePIPELINED ISv_character_record character_record := character_record(NULL);v_index NUMBER;v_split VARCHAR(30) := ';';v_content VARCHAR2(32767) := TRIM(v_split FROMp_parameter_value);BEGINIF v_content IS NULL THENRETURN;END IF;IF p_split_chars IS NOT NULL THENv_split := p_split_chars;END IF;LOOPv_index := instr(str1 => v_content, str2 => v_split);EXIT WHEN v_index = 0;v_character_record.value := substr(str1 => v_content,pos => 1,len => v_index - 1);v_content := substr(str1 => v_content,pos => v_index + 1);PIPE ROW(v_character_record);END LOOP;v_character_record.value := v_content;PIPE ROW(v_character_record);RETURN;END parse_multi_param;
即通过存储过程,将传入字符串参数,转化为临时表
3.2 往sql中拼接sql语句段
类似mybatis中的${}标签,这里是截取的lov中的一段写法
<bm:features><s:bm-script><![CDATA[var objectMap = $bm('expm.EXP5110.exp_mo_expense_object_types_query').queryAsMap();var objectArr = objectMap.getChildren();if (objectArr && objectArr.length == 1) {if (objectArr[0].expense_object_method == 'VALUE_LIST') {var sqlText = 'select v.mo_expense_object_id as id,v.mo_expense_object_code as code,v.mo_expense_object_name as name from exp_mo_expense_object_value_vl v where v.mo_exp_obj_type_id =' + $ctx.parameter.mo_exp_obj_type_id;$ctx.parameter.sqltext = sqlText;} else if (objectArr[0].expense_object_method == 'SQL_TEXT') {var sqlText = 'select id,code,name from (' + objectArr[0].sql_query + ')';$ctx.parameter.sqltext = sqlText;}}]]></s:bm-script></bm:features><bm:operations><!--${:参数的路径}--><bm:operation name="query"><bm:query-sql><![CDATA[select * from (${:/parameter/@sqltext}) #WHERE_CLAUSE#]]></bm:query-sql></bm:operation></bm:operations>
所以把3.1中数组传入改成逗号拼接字符串传入可能更方便。不过这里是有注入风险的。
Aurora开发备忘相关推荐
- 【ESP8266开发备忘】
目录 一.一些资料 eclipse AithinkerIDE平台 RTOS v3.0+ SDK平台 常见的两款开发板说明 AiThinkerIDE的常用操作快捷键 二.ESP8266 sdk3.0 i ...
- 苹果 Apple CarPlay开发备忘
1.建立iAP2通道 与Android Auto不同,Apple CarPlay需要通过苹果CP IC芯片鉴权,在iAP初期进行鉴权核对.否则无法继续通信. IC芯片需要单独购买. 2.切换苹果手机i ...
- iMX6UL lvgl开发备忘
文章目录 LV_conf.h 配置 LV_conf.h 配置 #define LV_COLOR_DEPTH 16
- STM32USB开发备忘之CDC_VCP实验
USB CDC类(communications device class)可用于设备与主机之间的USB通信.有了CDC,再也不需要USB-TTL转接板啦,数据传输也更快. 平台:STM32F405 内 ...
- 百度CarLife开发备忘
1.建立aoa通道 可以通过libusb直接打开手机端的aoa模式,发送百度CarLife描述信息.此后会重新枚举aoa设备,手机端会提示是否需要下载carlife. 也可以通过内核来建立一个aoa驱 ...
- php微信开发备忘-图片素材上传的一个坑
上传图片素材时一定要用数组去执行上传,不要用json数组去上传! 总之就是依照curl的上传方式去走!否则报41005!!! $data = array('media' =>'@'.realpa ...
- 亿连CarBit开发备忘
1.移植carbit开发包 与苹果CarPlay.谷歌AndroidAuto.百度CarLife不同,亿连的库已经通过libusb将通信层封装好了,不需要去处理usb层的通信和兼容.因此可以直接交叉编 ...
- aws dynamodb_DynamoDB备忘单–您需要了解的有关2020 AWS认证开发人员助理认证的Amazon Dynamo DB的所有信息
aws dynamodb The emergence of cloud services has changed the way we build web-applications. This in ...
- UWP开发入门教程备忘
UWP-01~03 略~ UWP-04 - 什么是XAML? XAML - 遵循XML语法,XAML实际上是在创建类的实例,并给它们设定属性值,用于定义UI UWP-05 - 类型转换器 类型转换器 ...
最新文章
- 购物商城Web开发第十二天
- wxpython设置listctrl选中行_Excel办公实操,进行给特定行(列),重复打印与避免打印...
- 如何“漂亮”地解决dota类游戏网络延迟同步?
- jquery事件重复绑定的几种解决方法 (二)
- 0 win10重装partition_教你在安装WIN10系统中所遇到问题处理方法
- 阿里云研究员叔同:云原生是企业数字创新的最短路径
- IT公司老板落水,各部门员工怎么救??
- mysql+使用swap_MySQL避免使用SWAP
- RHEL 6.4 安装DNS服务(bind-9.8 )
- 类别的作用?继承和类别在实现中有何区别
- python进阶 pdf_Python进阶(Intermediate_Python)_中文PDF彩色版.pdf
- 诊所 金卫系统 青岛_金卫信预防接种数字化门诊全程质量管理系统.doc
- springboot2 oauth2 jwt认证服务器和资源服务器
- IPV4地址详细解释
- 网络其他计算机无法访问,win7局域网别人无法访问我的电脑是为什么 win7其他电脑无法访问我的电脑如何修复...
- python PyEnchant(拼写检查)
- rest api是什么_什么是REST API?
- CSI笔记【12】:阵列信号处理及MATLAB实现(第2版)阅读随笔(四)
- Trino 本地编译搭建 standalone 模式
- 解决小程序-wx.canvasGetImageData()-RGB取色盘苹果手机获取颜色慢问题