前端页面脚本扩展
# 变更记录
| 产品版本 | 更新内容 | 更新日期 |
| --- | --- | --- |
| V7.0.1 | 发布了前端页面脚本功能,可以编写javascript代码,从而快速实现特定的业务控制逻辑等需求 | 2024-10-24 |
## 一、功能概述
通过前端页面脚本扩展功能,用户可以直接编写javascript代码,从而快速实现特定的业务控制逻辑
易于使用,对现有业务逻辑进行扩展操作简单(前提掌握脚本开发)
部署方便,脚本跟随元数据一起导入导出、补丁升级
支持内置API和组件事件等,增强了前端页面定制化开发能力
**如想快速查看相关定制效果,可直接点击"**[案例展示](https://vip.kingdee.com/article/588370901062560768?productLineId=29&isKnowledge=2&lang=zh-CN#9)**"阅读对应章节**
## 二、适用场景
以下场景可以考虑使用页面脚本扩展功能来实现:
1、想在前端页面快速实现一些简单的业务控制逻辑
2、依据页面数据状态等需要对某些UI元素做定制开发(比如修改内容展示格式,样式以及动画等)
3、开发的自定义控件其渲染数据依赖页面上字段等数据的变化,不想通过服务端插件实现
4、其他基于web页面轻量化JS脚本想实现的功能等
**注意**:
1、标准业务与二开项目等都可使用(有做权限控制)
2、**脚本在设计器中可进行编辑或查看,且考虑到web页面脚本的安全性等,不建议将重要或复杂的业务逻辑放在脚本中实现**
3、**如果想开发一个独立控件且需要与服务端插件通信,同时希望在不同单据页面可复用,则推荐使用[自定义控件](https://developer.kingdee.com/knowledge/specialDetail/218022218066869248?category=249447947539332864&id=205421332635100416&productLineId=29)做开发**
## 三、功能入口与界面介绍
该页面脚本功能分设计时与运行时,设计时可以编写/查看、启用/禁用脚本,运行时执行脚本。
### 1、设计时
#### 脚本编辑器
![image.webp](/download/0100c412ad9c38374aefbf9dc090e76352cd.webp)
(1)API列表
* 基于这些内置API可快速实现特定功能。双击API名称快速插入代码片段、鼠标悬浮右侧"!"号上展示对应API详细内容
(2)脚本代码编辑区域
* 在此编辑JS脚本。支持录入功能接口或控件key等场景,自动提示并展示下拉选项列表
(3)脚本"保存"按钮
* 点击直接保存脚本**(脚本保存不依赖设计器的"保存"操作,即无需再点击设计器右上角保存按钮)**
(4)脚本语法检查
* 检查脚本内容是否存在语法错误
#### 脚本编辑器入口
脚本编辑和打开脚本编辑器的入口都在表单设计器中。
##### 总入口
点击该入口,会打开脚本编辑器并加载对应脚本内容。
【旧版 - 表单设计器】
![image.webp](/download/0100322d63862f3646c5b0b7b944ce8b4608.webp)
【新版 - 表单设计器】
![image.webp](/download/0100dc3ea8f1d95f442b82801fb5ed880b36.webp)
##### 页面/组件事件绑定入口
点击该入口,会打开脚本编辑器并自动生成对应组件/页面的事件绑定代码(如果已绑定过事件则会自动定位到对应代码行位置)。
【旧版表单设计器 - 选中单据根节点 - 动作面板】
![image.webp](/download/010008300f1de80f411d8e6cb147818db33f.webp)
【旧版表单设计器 - 选中组件 - 动作面板】
![image.webp](/download/0100a95bf916304d4f2d909f761e9c5dbf31.webp)
【新版表单设计器 - 选中单据根节点 - 动作面板】
![image.webp](/download/0100ff279b925ced4bcb976d9dd011152353.webp)
【新版表单设计器 - 选中组件 - 动作面板】
![image.webp](/download/01005228a82b52d84ecab6a5451dbdf9d1b1.webp)
#### 脚本管理界面
脚本管理界面可查看单据自身及其父页面的脚本内容,同时如有编辑权限可启用/禁用当前页面脚本
【旧版表单设计器 - 选中根节点 - 页面脚本属性】
![image.webp](/download/0100bfea4719ec254e5c931813cc6f414b1e.webp)
(1)启用/禁用脚本
(2)点击"表单标识"列超链接,可查看对应脚本内容
【新版表单设计器 - 页面脚本管理页签】
![image.webp](/download/0100ce6bb11fac0c495a883198e37f9998a3.webp)
#### 权限控制
权限控制,与Java插件管理一致,设计器中相同开发商才允许编辑。
### 2、运行时
执行脚本
* 运行时打开一个单据,单据对应脚本就会执行。
* 当存在多份脚本时(即父页面也有脚本的情况),脚本执行顺序为:自顶向下,优先执行父页面脚本。
## 四、脚本编写规范与语法支持
脚本编写使用javascript,内置了一些脚本对象、API和标准事件等。
**一个单据页面自身只会有一份JS脚本,同时支持通过单据继承/扩展/复制等方式来继承父页面的脚本**。
### 脚本生命周期
![image.webp](/download/0100409bd6b4e2344ee4816dc75bb46ac756.webp)
脚本编写主要在两个大的生命周期函数中进行,分别为:didMount、willUnmount
#### didMount
* 单据初始化函数
* 执行初始化相关事务,比如注册组件事件监听、设置数据、执行DOM操作等
* 此函数在单据加载服务端插件后自动调用
**注意**:
**1、一般脚本代码的主要实现逻辑都建议在该函数中编写实现**
**2、该函数在页面业务数据加载完成之后执行(即"loaddata"请求)**
#### willUnmount
* 单据卸载函数
* 执行资源释放等事务,比如移除DOM事件监听/定时器、销毁UI元素、删除全局变量等
* 此函数在单据关闭(销毁)时自动调用
**注意:该函数在页面关闭时执行**
### 脚本事件绑定
#### didMount
单据初始化事件,设计器中选中单据根节点,右侧"**动作**"面板可看到对应事件绑定入口(**新增脚本默认自动生成**)
示例:
```
/**
* 单据初始化函数
* 执行初始化相关事务,比如注册组件事件监听、设置数据、执行DOM操作等
* 此函数在单据加载服务端插件后自动调用
*/
function didMount () {
}
```
#### willUnmount
单据卸载事件,设计器中选中单据根节点,右侧"**动作**"面板可看到对应事件绑定入口(**新增脚本会默认自动生成**)
示例:
```
/**
* 单据卸载函数
* 执行资源释放等事务,比如移除DOM事件监听/定时器、销毁UI元素、删除全局变量等
* 此函数在单据关闭(销毁)时自动调用
*/
function willUnmount () {
}
```
#### onValueChange
字段值更改事件,设计器中选中任意字段类型组件,右侧"**动作**"面板可看到对应事件绑定入口
* 字段值更改事件,在内容发生改变且字段输入框失去焦点时触发
* 后续会根据规划与需要开放更多组件的标准事件(比如按钮点击等)
示例:
```
// 事件参数结构说明:data: {key, newValue, oldValue}
this.$('字段标识').onValueChange((data) => {
// todo something
})
```
### 内置对象
"**this**":页面脚本上下文对象,用于访问页面内所有控件实例和获取页面自身相关数据。
* 该对象一般在didMount或willUnmount中使用,使用时注意要保证其指向正确(特别是在嵌套函数中),否则脚本会报错,无法正确访问相关对象或接口
示例:
```
function didMount() {
// this指向页面脚本上下文
this.xxx
//错误写法
this.$('控件标识').on('click',function(e){
//此时this不指向页面脚本上下文,js会报错
this.$('控件标识').set('Name','title')
})
//正确写法(使用箭头函数,自动绑定上下文)
this.$('控件标识').on('click',(e)=>{
//此时this指向页面脚本上下文,js正常执行
this.$('控件标识').set('Name','title')
})
}
function willUnmount() {
// this指向页面脚本上下文
this.xxx
}
// 此时this不指向页面脚本上下文(指向window对象)
this.xxx
```
"**this.$('控件标识')**":用于获取控件实例,使用该实例可调用控件相关功能接口(包括通用控件方法、字段方法等)
示例:
```
// 获取控件实例对象
this.$('控件标识')
//调用控件实例对象功能接口
this.$('控件标识').set('Name', 'title')
```
### export关键字
如果将某些逻辑封装为独立的函数,且函数中用到了脚本内置对象或API等,为了在函数中能正常访问这些对象或API等,则需要为函数增加**export**修饰关键字,同时函数调用方式为: **this.独立函数名称()**。
示例:
```
// 初始化
function didMount() {
this.testMethod() //调用函数
}
// 独立函数写法
export function testMethod(str) {
this.$('控件标识').setValue('111')
}
```
### 与自定义控件通信
标准字段值变化要通知自定义控件,需要调用invoke接口。
具体示例代码见 "**案例展示 - 标准字段与自定控件通信**"部分内容。
## 五、API介绍
页面脚本编写,预制了部分API,提升代码编写效率与使用体验。
具体API及其分组如下:
### 1、通用控件方法
#### set
设置控件属性值(支持所有控件,属性名称可在设计器右侧属性面板查看)
格式:
```
this.$('控件标识').set('属性名', '属性值')
```
示例:
```
this.$('textfield1').set('Name', 'title')
```
#### get
获取控件的属性值(属性名称可在设计器右侧属性面板查看)
格式:
```
this.$('控件标识').get('属性名')
```
示例:
```
this.$('textfield1').get('Name')
```
#### isEditable
获取控件锁定性,即控件是否可编辑
格式:
```
this.$('控件标识').isEditable()
```
示例:
```
this.$('textfield1').isEditable()
```
#### isVisible
获取控件可见性,即是否被隐藏
格式:
```
this.$('控件标识').isVisible()
```
示例:
```
this.$(textfield1').isVisible()
```
### 2、字段方法
#### setValue
设置字段值
格式:
```
this.$('控件标识').setValue('值内容')
```
示例:
```
this.$('textfield1').setValue('123')
```
#### getValue
获取字段值
格式:
```
this.$('控件标识').getValue()
```
示例:
```
this.$('textfield1').getValue()
```
#### isRequired
获取字段必录属性,表明该字段是否是必须录入的
格式:
```
this.$('控件标识').isRequired()
```
示例:
```
this.$('textfield1').isRequired()
```
### 3、表单方法
#### getFormConfig
获取当前表单的配置信息,包含表单相关配置项
示例:
```
this.getFormConfig()
```
#### getFormMeta
获取当表表单的元数据,包含所有组件的布局等描述信息
示例:
```
this.getFormMeta()
```
#### getFormStatus
获取当前表单的单据状态,其返回数据含义:0/新增、1/修改、2/查看、4/提交、5/审核
示例:
```
this.getFormStatus()
```
### 4、DOM操作方法
**注意:DOM相关操作如果依赖控件对应DOM结构上的某个子元素,请谨慎使用,后续版本迭代升级无法保证DOM结构不会变化**。
#### on
用于为DOM元素添加事件监听,接受三个参数:事件名称(HTML原生事件,可同时监听多个,用空格分隔)、子元素选择器 【可选】、事件回调函数
格式:
```
this.$('控件标识').on('html事件名称', 事件回调函数)
```
示例:
```
const handler=event=>{...}
this.$('textfield1').on('mouseenter mouseleave', handler)
```
#### off
用于移除DOM元素的事件监听,可移除通过'on'接口监听的所有或特定事件
格式:
```
this.$('控件标识').off('html事件名称', 事件回调函数)
```
示例:
```
const handler=event=>{...}
this.$('textfield1').off('mouseenter mouseleave',handler)
```
#### getElement
获取控件对应的DOM对象
格式:
```
this.$('控件标识').getElement()
```
示例:
```
let dom = this.$('textfield1').getElement()
dom.style.height = 100
```
#### wait
用于控件懒加载时,异步获取组件对应DOM对象
格式:
```
this.$('控件标识').wait().then(ctrlDomEle => {})
```
示例:
```
this.$('textfield1').wait().then(ctrlDomEle =>
console.log(ctrlDomEle.style.height)
)
```
#### css
设置控件内联样式,支持修改单个或多个html样式属性
格式:
```
this.$('控件标识').css({'css属性名称':'属性值'})
```
示例:
```
this.$('textfield1').css('background','red')
this.$('textfield1').css({'background':'red', 'color':'#666666'})
```
### 5、工具类函数
#### loadFiles
加载资源文件,动态加载第三方资源文件(比如js、css等)
格式:
```
this.utils.loadFiles(['文件路径1','文件路径2']).then(result => {})
```
示例:
```
this.utils.loadFiles(['https://www.xxx.com/xxx/123.js','https://www.xxx.com/xxx/456.css']).then(result => {
console.log(result)
})
```
#### showMessage
显示消息提示
用于弹出消息提示,接受两个参数:消息内容和可选的配置对象。配置对象中包含type(消息类型,可选值为0-成功,1-错误,2-警告)和duration(显示时长/ms)
格式:
```
this.utils.showMessage('消息内容')
```
示例:
```
this.utils.showMessage('content',{type:0,duration:3000})
```
#### createStyle
创建页面样式
动态创建< style >元素并插入到浏览器页面中,当前表单销毁时自动移除
格式:
```
this.utils.createStyle('css样式内容')
```
示例:
```
this.utils.createStyle(".root{width: 10px;} .sel{display: flex}")
```
#### loadArtTemplate
基于模版创建DOM元素
导入art模版库,方便创建dom元素
格式:
```
this.utils.loadArtTemplate().then(template => {})
```
示例:
```
this.utils.loadArtTemplate().then(template => {
const id='testSelect', title='this is test art template'
const str=`
`
const items = [{ id: 1, caption: '浅色主题' }, { id: 2, caption: '深色主题' }, { id: 3, caption: '跟随系统' }]
const htmlString = template.render(str, { items })
// 将下拉面板内容给到子div渲染
childDiv.innerHTML = htmlString
// 绑定处理下拉项点击事件
this.$('kdtest_buttonap3').on('click','li', (e)=>{
alert('你选择了:' + e.target.outerText);
})
})
}
})
}
```
【效果截图】
![image.webp](/download/0100b588d187868541a58b6edf6abc153394.webp)
![image.webp](/download/0100e39f80dbd8624d478987425fcb3b5d12.webp)
### 6、自定义按钮点击
【功能场景】:业务或二开需要在前端页面上某个标准按钮被点击时,做一些自定义的页面逻辑实现,不依赖服务端插件
【实现思路】:通过原生click事件监听按钮点击(后续标准事件也可能支持)
```
// 单据初始化函数
function didMount() {
// 'kdtest_buttonap1':按钮标识;【实现思路】:通过原生click事件监听按钮点击(后续标准事件也可能支持)
this.$('kdtest_buttonap1').on('click', (e) => {
window.alert('你点击了按钮');
})
}
```
### 7、标准字段与自定义控件通信
【功能场景】:开发的自定义控件其渲染依赖页面上某些字段的数据,所以需要在这些字段数据有变化时通知到自定义控件内部,从而刷新自定义控件内部数据并重新渲染,不依赖服务端插件
【实现思路】:
1、监听文本字段值变化事件,在事件回调中调用控件通用消息接口‘**inovke**’向自定义控件发送消息
2、自定义控件内部接收页面JS脚本消息:在自定义控件内部(入口文件index.js)已有方法'**handleDirective**'中处理([方法介绍](https://developer.kingdee.com/knowledge/specialDetail/218022218066869248?category=249447947539332864&id=329617446174701824&productLineId=29&lang=zh-CN#8))
JS脚本代码示例:
```
// 单据初始化函数
function didMount() {
// 字段值变化时向自定义控件内部发送消息
//'kdtest_textfield':字段组件标识
this.$('kdtest_textfield').onValueChange((data) => {
//'customcontrolap':要接收消息的自定义控件标识;invoke接口参数说明:方法名称(自定义)、方法参数(自定义)
this.$('customcontrolap').invoke('textFieldValueChange01',{a1: '1121', data: data.newValue});
})
}
```
自定义控件内部代码示例(index.js):
```
//自定义控件内部接收页面JS脚本消息:在自定义控件内部已有方法handleDirective中处理
handleDirective: function ((customProps, methodname, arg){
//按照上面JS脚本示例调用脚本,此时该方法参数值为:methdoname=> 'textFieldValueChange01' arg=>{a1: '1121', data: data.Value}
if(methodname == 'textFieldValueChange01'){
alert(arg.data);
}
}
```
## 十、脚本部署与迁移(导入导出)
### 脚本发补丁
页面脚本在服务端是独立的数据库表存储,脚本与单据的关联关系数据是存储在单据元数据中的。
如果是制作标准补丁,则在开发平台导出页面数据(**此时页面脚本和页面元数据会一起导出,页面脚本文件扩展名'.ks'**)再提交到对应元数据目录即可。
![image.webp](/download/010084cdc9241ebd447aa372e0bf31d87f37.webp)
### 脚本迁移(导入导出)
如何将页面脚本从一个环境迁移到另一个环境?
答:基于开发平台的导入导出功能,将单据和对应页面脚本从一个环境导出,再导入另一个环境即可
【开发平台 - 导出】
!![image.webp](/download/0100c475c64f977c47c59d3e7f85c41082c5.webp)
【开发平台 - 导入】
![image.webp](/download/0100f99f038ba80e4b1e967c8ecaf028deed.webp)
**注意:在开发平台手工导入页面(包含页面脚本),如果页面有依赖其他单据比如父页面等,需要先导入父页面,否则导入会有异常,脚本内容也会导入失败**。
## 十一、注意事项
1、IE浏览器暂不支持脚本编辑,可执行脚本。
2、'**set**'接口设置属性可能会被服务端插件设置内容覆盖(原因是服务端插件修改生效优先级>=页面脚本)。
3、脚本执行异常(未捕获的),则后续脚本执行中断。
4、通过'**on**'接口监听组件DOM事件,该事件不会与组件内部状态联动。比如锁定的按钮,通过on接口监听其'click'点击事件,即使按钮通过被锁定了,事件依然会触发。
5、**'set'接口支持的参数(控件属性)有限,一般都是与样式设置相关**。参数获取示例:修改控件宽度,其参数获取方法(设计器中鼠标放到对应属性名称上即可查看到参数名称“Width”),如下截图:
![image.webp](/download/0100346091be5b3040e3b8c65014b70e1b28.webp)
**备注:为保证已有业务逻辑的正确性,锁定性、可见性、必录、控件标识、类型等控件属性不支持通过脚本修改**
6、'**createStyle**'接口创建Class限制其作用域在当前单据页面(防止全局样式污染)。
7、使用'**setValue**'接口为基础资料类型字段赋值会引发服务端报错,原因是基础资料字段赋值是要在服务端先赋值,再刷新前端组件(这与文本字段等不同)。
8、**历史单据新增页面脚本,脚本保存之后需要再做一次设计器的保存,否则脚本内容会丢失**。
9、脚本中标准事件或其他API接口(比如on)中使用的回调函数建议使用箭头函数写法,可自动绑定上下文,保证在函数中可正常访问脚本内置对象等。
## 十二、常见问题与解决方法
暂无
## 十三、*技术支持*与资源
### 学习资源
JavaScript脚本学习[教程](/tolink?target=https://www.w3school.com.cn/js/index.asp)
### 技术支持
建议方式如下:
1、[苍穹开发者论坛](https://developer.kingdee.com/developer?productLineId=29)发帖、
2、KSM系统提单、
3、需求反馈: qiao_wen@kingdee.com
<label for='id'>title</label><select name="pets" id='id'>{{each items}}<option value={{$value.id}}>{{$value.caption}}</option>{{ /each}}</select>
`
const items = [{id:1,caption:'name1'},{id:2,caption:'name2'}]
const htmlString = template.render(str,{items})
document.getElementById('select').innerHTML = htmlString
})
```
### 6、其他方法
#### debugger
调试代码
在js脚本中设置断点,从而支持打开浏览器控制台后调试代码
示例:
```
debugger
```
#### console
输出日志
在浏览器控制台输出日志信息
示例:
```
console.log('日志信息')
```
## 六、DOM相关操作
页面脚本目前支持标准的事件(比如字段值改变事件等,后续也会开放更多),数据获取与赋值等操作也有标准的功能接口(比如getValue、setValue等),通过标准事件与功能接口可以快速实现相关业务逻辑。
**有些页面交互行为或数据是标准组件/接口没有对外提供或暂未规划的,此时通过组件相关DOM对象的相关操作可以变相的快速实现**。
比如:
* 通过DOM对象的'input'事件可以实时监听字段值改变,事件触发时机是实时的(标准字段是失去焦点时才触发)
* 通过DOM对象的'click'事件监听标准按钮的点击事件,在前端页面通过脚本实现相应业务逻辑
**DOM对象事件操作可能对标准组件存在影响,请谨慎使用。**
DOM对象监听的事件为HTML DOM原生事件,具体可参考[DOM原生事件](/tolink?target=https://www.w3school.com.cn/jsref/dom_obj_event.asp)。
DOM相关操作内置的API包括:on、off、getElement、wait、css,具体描述见"**API介绍**"章节。
## 七、如何引用第三方JS、CSS等资源
可通过加载第三方资源的API:'**this.utils.loadFiles**' 实现(**请保证自己引用的 JS等资源文件的安全性**)。
示例:
```
// 初始化
function didMount() {
// 加载资源
this.utils.loadFiles(['https://www.xxx.com/xxx/123.js','https://www.xxx.com/xxx/456.css']).then(result=> {
console.log(result)
})
}
```
## 八、如何调试与异常处理
### 脚本代码调试
1、在脚本中使用"**debugger**"关键字
运行时打开浏览器控制台/开发者工具,即可命中该断点,进入脚本调试
脚本发布上线前建议删除调试代码(即"**debugger**"关键字)
![image.webp](/download/0100d6c160048ef74d73991749b7d0a20ea9.webp)
2、通过输出日志来反向定位脚本并打断点
在脚本中任意输出一条日志,比如使用'console.log(日志信息)',运行时输出的该日志会有对应文档链接,
点击控制台输出的日志其最右边的链接,浏览器会自动打开对应脚本内容,此时再手动打断点,下次脚本运行到这里就会进入调试。
示例如下:
![image.webp](/download/01003488641304884ac79eb9658f88479360.webp)
### 异常处理
1、脚本中调用内置的标准功能接口(比如“this.$('控件标识').接口名称”),有默认做一些异常捕获,比如控件标识不存在,接口不存在等情况,此时浏览器控制台会有异常信息提示,且**后续脚本会继续执行**。
示例如下:
![image.webp](/download/0100e3e4a1324c474080a966d9a9e2caf89f.webp)
2、当用户自己编写的脚本内容引发了异常(比如访问一个不存在对象的某个属性,例如访问a.b但对象a不存在),同时**没有捕获异常时,后续脚本执行就会终止**。
## 九、案例展示
### 1、大小写字母实时自动转换
【功能场景】:需要将用户录入的小写英文字母自动并实时转为大写英文字母
【实现思路】:在字段中输入框的原生input事件中做转换,再重新赋值
```
// 初始化
function didMount() {
// 'kdtest_textfield':文本字段标识;
this.$('kdtest_textfield').on('input', 'input', (e) => {
// 给字段赋值
setTimeout(()=>{
// setTimeout一下,键盘录入时字母变为大写会有动态过程
this.$('kdtest_textfield').setValue(convertToUpperCase(e.target.value))
},100)
})
}
/**
* 字母转换为大写
*/
function convertToUpperCase(str) {
return str.toUpperCase();
}
```
【效果截图】
![image.webp](/download/010009bb069a48e047afa1b69a64de68cb04.webp)
### 2、阿拉伯数字转中文数字
【功能场景】:需要将用户录入的阿拉伯数字自动转为中文数字
【实现思路】:在字段值改变的标准事件中做数字转换,再重新赋值
```
// 初始化
function didMount() {
// kdtest_textfield3:文本字段标识;
this.$('kdtest_textfield3').onValueChange((data) => {
let result = convertToChineseNumber(data.newValue)
this.$('kdtest_textfield3').setValue(result)
})
}
/**
* 将字符串中数字转换为大写数字
*/
function convertToChineseNumber(str) {
// 正则表达式匹配字符串中的所有数字
const regex = /\d+/g;
// 替换函数,将匹配到的数字转换为中文数字
return str.replace(regex, (match) => {
const num = parseInt(match, 10); // 将匹配到的字符串转换为数字
const chineseNumbers = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
// 将数字转换为中文数字字符串
let chineseStr = '';
for (let i = 0; i < num.toString().length; i++) {
chineseStr += chineseNumbers[parseInt(num.toString()[i], 10)];
}
return chineseStr;
});
}
```
【效果截图】
![image.webp](/download/0100da1e66b3cc8a45e29bd2cd2f4c81a19d.webp)
### 3、字段联动,比如做两个数字合计等
【功能场景】:根据页面上某些字段的数据,做二次的合计功能(比如求和或更复杂操作等)
【实现思路】:值改变时做合计,再给显示合计结果的字段赋值
```
// 单据初始化函数
function didMount() {
// 合计值1-值改变事件;kdtest_integerfield1:整数字段标识;
this.$('kdtest_integerfield1').onValueChange((data) => {
// 求和,给合计字段赋值
this.$('kdtest_integerfield').setValue(parseInt(data.newValue) + parseInt(this.$('kdtest_integerfield2').getValue()))
})
// 合计值2-值改变事件;kdtest_integerfield2:整数字段标识;
this.$('kdtest_integerfield2').onValueChange((data) => {
//求和,给合计字段赋值
this.$('kdtest_integerfield').setValue(parseInt(data.newValue) + parseInt(this.$('kdtest_integerfield1').getValue()))
})
}
```
【效果截图】
![image.webp](/download/0100c35f768f1288449386515f0db609976e.webp)
### 4、根据字段值变化做样式修改
【功能场景】:根据页面上某个组件的数据变化,动态修改其他组件的样式,比如实现一个下拉字段值变化时动态修改自身文字颜色
【实现思路】:在下拉字段切换值触发值改变事件的回调中,修改其输入框前景色
```
// 单据初始化函数
function didMount() {
// kdtest_combofield:下拉字段标识;
this.$('kdtest_combofield').onValueChange((data) => {
let colorValue //下拉字段选择的颜色
switch (data.newValue) {
case 'red':
colorValue = 'red'
break;
case 'yellow':
colorValue = 'yellow'
break;
case 'blue':
colorValue = 'blue'
break;
default:
window.alert("未处理的值: " + data.newValue)
}
const selectEle = this.$('kdtest_combofield').getElement()
if (selectEle) {
// 这里用到一个全局开放CSS: "kd-cq-combo-selected",用于快速定位输入框文字
const inputElement = selectEle.querySelector('.kd-cq-combo-selected')
if (inputElement) {
// 设置前景色(文字颜色)
inputElement.style.color = colorValue
}
}
})
}
```
【效果截图】
![image.webp](/download/0100e56b11e69d5a440aafb2baf89a5c1dd4.webp)
### 5、标准按钮增加下拉面板
【功能场景】:想扩展现有标准组件实现UI功能定制开发,比如基于标准按钮在点击时实现一个下拉面板并支持点击面板上选项
【实现思路】:通过on接口监听按钮原生click事件,在回调中动态生成下拉面板并且通过on接口监听下拉面板的下拉选项点击事件
```
// 单据初始化函数
function didMount() {
// kdtest_buttonap3:按钮标识;
this.$('kdtest_buttonap3').on('click', (e) => {
const parentDiv = this.$('kdtest_buttonap3').getElement()
// 防止重复处理
if (parentDiv && !document.getElementsByClassName('__myChildDivClass__')[0]) {
// 创建新的子div元素
let childDiv = document.createElement('div');
// 设置子div的样式类
childDiv.className = '__myChildDivClass__';
// 设置子div的id值、显示位置
childDiv.id = '__myChildDivClass__';
let parentPostion = parentDiv.getBoundingClientRect()
childDiv.style.left = parentPostion.left + "px";
childDiv.style.top = parentPostion.top + parentPostion.height + 2 + "px";
childDiv.style.width = parentPostion.width + "px";
// 将子div添加到父div内
parentDiv.appendChild(childDiv);
// 增加下拉面板样式
this.utils.createStyle('.__myChildDivClass__{background: lightgray;position:fixed;z-index: 1;} .themeselect_div{display: flex;flex-direction: column;color:black;} .themeselect_title{background: darkgray;}')
//创建下拉面板内容
this.utils.loadArtTemplate().then(template => {
const id = 'themeSetting', title = '主题色设置'
const str = `${title}
-
{{each items}}
- {{$value.caption}}</option> {{ /each}}
前端页面脚本扩展
# 变更记录| 产品版本 | 更新内容 | 更新日期 || --- | --- | --- || V7.0.1 | 发布了前端页面脚本功能,可以编写javasc...
点击下载文档
上一篇:如何调试Echarts下一篇:容器控件——轮播容器
本文2024-09-23 00:39:58发表“云苍穹知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-cangqiong-140943.html
您需要登录后才可以发表评论, 登录登录 或者 注册
最新文档
热门文章