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}&amp;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 &apos;%&apos; || ${@tax_type_code} || &apos;%&apos;"/><bm:query-field name="tax_type_name" queryExpression="v.tax_type_name like &apos;%&apos; || ${@tax_type_name} || &apos;%&apos;"/></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开发备忘相关推荐

  1. 【ESP8266开发备忘】

    目录 一.一些资料 eclipse AithinkerIDE平台 RTOS v3.0+ SDK平台 常见的两款开发板说明 AiThinkerIDE的常用操作快捷键 二.ESP8266 sdk3.0 i ...

  2. 苹果 Apple CarPlay开发备忘

    1.建立iAP2通道 与Android Auto不同,Apple CarPlay需要通过苹果CP IC芯片鉴权,在iAP初期进行鉴权核对.否则无法继续通信. IC芯片需要单独购买. 2.切换苹果手机i ...

  3. iMX6UL lvgl开发备忘

    文章目录 LV_conf.h 配置 LV_conf.h 配置 #define LV_COLOR_DEPTH 16

  4. STM32USB开发备忘之CDC_VCP实验

    USB CDC类(communications device class)可用于设备与主机之间的USB通信.有了CDC,再也不需要USB-TTL转接板啦,数据传输也更快. 平台:STM32F405 内 ...

  5. 百度CarLife开发备忘

    1.建立aoa通道 可以通过libusb直接打开手机端的aoa模式,发送百度CarLife描述信息.此后会重新枚举aoa设备,手机端会提示是否需要下载carlife. 也可以通过内核来建立一个aoa驱 ...

  6. php微信开发备忘-图片素材上传的一个坑

    上传图片素材时一定要用数组去执行上传,不要用json数组去上传! 总之就是依照curl的上传方式去走!否则报41005!!! $data = array('media' =>'@'.realpa ...

  7. 亿连CarBit开发备忘

    1.移植carbit开发包 与苹果CarPlay.谷歌AndroidAuto.百度CarLife不同,亿连的库已经通过libusb将通信层封装好了,不需要去处理usb层的通信和兼容.因此可以直接交叉编 ...

  8. 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 ...

  9. UWP开发入门教程备忘

    UWP-01~03 略~ UWP-04 - 什么是XAML? XAML - 遵循XML语法,XAML实际上是在创建类的实例,并给它们设定属性值,用于定义UI UWP-05 - 类型转换器 类型转换器 ...

最新文章

  1. 购物商城Web开发第十二天
  2. wxpython设置listctrl选中行_Excel办公实操,进行给特定行(列),重复打印与避免打印...
  3. 如何“漂亮”地解决dota类游戏网络延迟同步?
  4. jquery事件重复绑定的几种解决方法 (二)
  5. 0 win10重装partition_教你在安装WIN10系统中所遇到问题处理方法
  6. 阿里云研究员叔同:云原生是企业数字创新的最短路径
  7. IT公司老板落水,各部门员工怎么救??
  8. mysql+使用swap_MySQL避免使用SWAP
  9. RHEL 6.4 安装DNS服务(bind-9.8 )
  10. 类别的作用?继承和类别在实现中有何区别
  11. python进阶 pdf_Python进阶(Intermediate_Python)_中文PDF彩色版.pdf
  12. 诊所 金卫系统 青岛_金卫信预防接种数字化门诊全程质量管理系统.doc
  13. springboot2 oauth2 jwt认证服务器和资源服务器
  14. IPV4地址详细解释
  15. 网络其他计算机无法访问,win7局域网别人无法访问我的电脑是为什么 win7其他电脑无法访问我的电脑如何修复...
  16. python PyEnchant(拼写检查)
  17. rest api是什么_什么是REST API?
  18. CSI笔记【12】:阵列信号处理及MATLAB实现(第2版)阅读随笔(四)
  19. Trino 本地编译搭建 standalone 模式
  20. 解决小程序-wx.canvasGetImageData()-RGB取色盘苹果手机获取颜色慢问题

热门文章

  1. 解决魅族应用中心淘宝广告SQL
  2. 名帖66 欧阳询 小楷《黄帝阴符经》
  3. A股疯涨,没被收割前,没人觉得自己是韭菜
  4. 基于java的学生学籍信息管理系统
  5. 亲测好用【2023最新版】微信僵尸粉清理软件免费
  6. QTP自动化测试过程解析
  7. 01-Spring初识
  8. JS三目运算符失效原因(小程序)
  9. 微信小程序授权登录界面
  10. 强化学习笔记:多臂老虎机问题(1)