原有表单默认值只能通过同步方法的返回值,在一些需要网络请求才能获取值的情况下(如获取人员组织数据、数据字典等情况),同步请求造成阻塞,降低了页面的响应速度。本文介绍这种情况下的异步处理方式。(本文适用前端脚本)
表单组件的默认值可以返回一个Promise,来实现异步。(5.3及后续版本支持)
可使用异步返回的组件和属性
组件 | 脚本 |
文本(Label) | 值 (脚本) |
文本字段(Textfield) | 默认值 |
数字字段(Number) | 默认值 |
人员组织(Org) | 默认值脚本 职务脚本 |
日期(Calendar) | 默认值 |
多行文本(Textarea) | 默认值 |
下拉框(Select) | 默认值 可选值脚本 |
单选框 | 默认值 可选值脚本 |
多选框 | 默认值 可选值脚本 |
数据网格 | 默认值 |
异步返回服务器时间
表单上创建日期选择组件,并在默认值脚本中使用如下代码:
//true表示异步,此时返回一个Promise return Date.getFromServer(true);
异步获取组织数据
脚本中可以通过this.org对象获取组织数据。在以前的版本中,this.org中的方法都是同步的,现在可以使用异步方式获取组织数据。
例一:在表单中创建一个人员组织组件,如要获取创建人所在的第二层组织作为默认值,可在默认值脚本中添加如下代码:
//最后一个参数true表示异步,返回一个Promise return this.org.getUnitByIdentity(this.workContext.getWork().creatorIdentityDn, 2, true);
例二:假设要获取创建身份所在组织的所有身份数量,作为一个数字字段的值,可以在数字字段的默认值脚本中使用如下代码:
//先获取了创建身份所在的直接组织,再获取此组织的所有身份成员,返回成员的数量,作为数字字段的值。 return this.org.getUnitByIdentity(this.workContext.getWork().creatorIdentityDn, null, function (unit) { return this.org.listIdentityWithUnit(unit, false, function (ids) { return ids.length; }); }.bind(this));
异步获取数据字典
在以前的版本中,this.Dict对象的get方法是同步的,现在可以使用异步方式使用get方法。
例:假设以一个数据字典中的数据作为表单中数据网格的默认值,可以按如下方式进行:
1、创建数据字典如下图:
在表单中设计一个数据网格:
在数据网格默认数据中添加以下脚本:
var dict = new this.Dict("test"); //异步使用数据字典的get方法时返回Promise return dict.get("tools", true);
通过平台 Actions对象调用服务
通过脚本this.Actions调用平台服务,异步时默认返回Promise,可以作为表单元素的默认值。
例:假设要获取所有内容管理栏目名称作为下拉框的可选列表,可在下拉框可选值脚本中使用以下代码:
return this.Actions.load("x_cms_assemble_control").CategoryInfoAction.listAllCategoryInfo(function(json){ return json.data.map(function(d){ return d.appName; }); });
通过原生javascript或其他框架发起的异步请求
例一:通过原生js发起异步请求。本例中,发起http请求获取index.html内容,将内容作为一个多行文本的值。可以在多行文本的默认值脚本中使用以下代码:
//返回一个Promise return new Promise(function(resolve, reject){ var oReq = new XMLHttpRequest(); //绑定load事件 oReq.addEventListener("load", function(){ resolve(oReq.responseText); }); oReq.open("GET", "index.html"); oReq.send(); });
例二:通过Jquery发起异步请求,功能和例一相同
//确保jquery已经引入 //返回一个Promise return new Promise(function(resolve, reject){ $.get("index.html", function (data) { resolve(data); }); });
脚本中的其他注意事项
表单组件的getValue方法
1、组件的getValue方法异步处理时会返回一个Promise实例(同步时或异步处理已经完成,返回组件的实际值),通过promise.then(function(value){});方法进行后续处理,或直接通过Promise.resolve(module.getValue()).then(function(value){});来处理。
例:假设表单的人员组件org使用异步函数作为默认值,在表单中的数字组件要使用org组件值的数量作为默认值,可在数字组件的默认值脚本中使用以下代码:
var v = this.form.get("org").getValue(); if (v.then){ return v.then(function(value){ return value.length; }); }else{ return v; } //或者 var v = this.form.get("org").getValue(); return Promise.resolve(v).then(function(value){ return value.length; })
this.data.xxx的getter和setter
通过this.data.xxx赋值时,可通过赋值一个Promise对象,通过this.data.xxx获取业务数据时,可能获取到Promise对象(异步请求正在执行中)。请看下面的代码:
//创建一个Promise对象 var p = new Promise(function(resolve, reject){ //载入Jquery o2.load("jquery", function(){ //防止jquery冲突 jQuery.noConflict(); var done = function (data) { resolve(data); //返回响应的内容 }; //发起get请求 jQuery.get("index.html", done); }); }); //将业务数据textarea赋值为promise this.data.textarea_2 = p; //此时获取到的值是promise console.log(this.data.textarea_2); p.then(function(){ //此时获取的是textarea中最终存储的值(本例中是index.html的内容) console.log(this.data.textarea_2); }.bind(this));
组件的getData方法
通过组件的getData方法获取的是组件的当前显示值,如果给组件赋值一个Promise对象,在异步执行完成之前,getData获取到的是组件当前的显示值。请看以下代码:
//获取到文本组件 var field = this.form.get("textfield"); this.data.textfield = "oa"; console.log(field.getData()); //输出 oa //异步获取创建人所在第二层组织,返回Promise对象 var p = this.org.getUnitByIdentity(this.workContext.getWork().creatorIdentityDn, 2, function(unit){ return unit.name; }); //给textfield赋值 this.data.textfield = p; //此时由于异步请求没有执行完毕,getData方法获取到的是原来的值 console.log(field.getData()); //输出 oa p.then(function(){ //此时由于异步请求已经执行完毕,getData方法获取到的是组织的名称 console.log(field.getData()); //输出 组织名称 });
若有收获,就点个赞吧