Aurora开发备忘

1 篇文章 0 订阅
1 篇文章 0 订阅

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'){
   		//修改查询用的bm
       record.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[
                SELECT
                    v.*
                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[
     SELECT
         h.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_name
     FROM
         pur_requisition_headers h
     WHERE
         h.req_number IN (
         (SELECT
             *
         FROM
             TABLE(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_table
    PIPELINED IS
    v_character_record character_record := character_record(NULL);
    v_index            NUMBER;
    v_split            VARCHAR(30) := ';';
    v_content          VARCHAR2(32767) := TRIM(v_split FROM
                                               p_parameter_value);
  BEGIN
    IF v_content IS NULL THEN
      RETURN;
    END IF;
    IF p_split_chars IS NOT NULL THEN
      v_split := p_split_chars;
    END IF;
    LOOP
      v_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中数组传入改成逗号拼接字符串传入可能更方便。不过这里是有注入风险的。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值