mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 03:48:13 +08:00
feat:补充一些通用动作&完善事件动作机制示例 (#3495)
* feat:补充一些通用动作&完善事件动作机制示例 * feat:补充一些通用动作&完善事件动作机制示例
This commit is contained in:
parent
37c5b8e673
commit
8cc8283ded
@ -1,6 +1,6 @@
|
||||
export default {
|
||||
type: 'page',
|
||||
title: '广播事件',
|
||||
title: '广播(自定义事件)',
|
||||
regions: ['body', 'toolbar', 'header'],
|
||||
body: [
|
||||
{
|
||||
@ -12,21 +12,9 @@ export default {
|
||||
title: '系统提示',
|
||||
body: '对你点击了'
|
||||
},
|
||||
// target: 'form?name=lvxj',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'reload',
|
||||
args: {
|
||||
name: 'lvxj',
|
||||
age: 18
|
||||
},
|
||||
preventDefault: true,
|
||||
stopPropagation: false,
|
||||
componentId: 'form_001'
|
||||
// componentId: 'form_001_form_01_text_01'
|
||||
},
|
||||
{
|
||||
actionType: 'broadcast',
|
||||
eventName: 'broadcast_1',
|
||||
@ -60,7 +48,6 @@ export default {
|
||||
title: '系统提示',
|
||||
body: '对你点击了'
|
||||
},
|
||||
// target: 'form?name=lvxj',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
@ -231,105 +218,6 @@ export default {
|
||||
actionType: 'custom',
|
||||
script:
|
||||
"doAction({actionType: 'ajax',api: 'https://api/form/form3-custom-ajax-1'});\n //event.stopPropagation();"
|
||||
},
|
||||
{
|
||||
actionType: 'parallel',
|
||||
args: {
|
||||
level: 3
|
||||
},
|
||||
children: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-parallel-ajax-1',
|
||||
preventDefault: false
|
||||
// stopPropagation: true
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-parallel-ajax-2'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
actionType: 'switch',
|
||||
preventDefault: false,
|
||||
stopPropagation: false,
|
||||
children: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-branch-ajax-1',
|
||||
expression: 'this.branchCont > 19',
|
||||
preventDefault: false,
|
||||
stopPropagation: true // 这里无效,因为条件不成立
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-branch-ajax-2',
|
||||
expression: 'this.branchCont > 17',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-branch-ajax-3',
|
||||
expression: 'this.branchCont > 16'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
actionType: 'loop',
|
||||
loopName: 'loopData',
|
||||
preventDefault: false,
|
||||
stopPropagation: false,
|
||||
args: {
|
||||
level: 3
|
||||
},
|
||||
children: [
|
||||
{
|
||||
actionType: 'reload',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-loop-ajax-1?name=${name}',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
},
|
||||
// {
|
||||
// actionType: 'break'
|
||||
// },
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-loop-ajax-2?age=${age}'
|
||||
},
|
||||
{
|
||||
actionType: 'loop',
|
||||
loopName: 'loopData',
|
||||
args: {
|
||||
level: 3
|
||||
},
|
||||
children: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-loop-loop-ajax-1'
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-loop-loop-ajax-2?age=${age}',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
},
|
||||
{
|
||||
actionType: 'continue'
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/form3-loop-loop-ajax-3'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
91
examples/components/EventAction/Cmpt.jsx
Normal file
91
examples/components/EventAction/Cmpt.jsx
Normal file
@ -0,0 +1,91 @@
|
||||
export default {
|
||||
type: 'page',
|
||||
title: '触发其他组件动作',
|
||||
regions: ['body', 'toolbar', 'header'],
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_001',
|
||||
label: '触发表单1的刷新动作',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'reload',
|
||||
args: {
|
||||
name: 'lvxj',
|
||||
age: 18
|
||||
},
|
||||
preventDefault: true,
|
||||
stopPropagation: false,
|
||||
componentId: 'form_001'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_002',
|
||||
label: '触发表单1的子表单1的输入框【名字】的清空动作',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'clear',
|
||||
preventDefault: true,
|
||||
stopPropagation: false,
|
||||
componentId: 'form_001_form_01_text_01'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
id: 'form_001',
|
||||
title: '表单1',
|
||||
name: 'form1',
|
||||
debug: true,
|
||||
data: {
|
||||
selfname: 'selfname' // 测下数据链
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
id: 'form_001_form_01',
|
||||
title: '表单1的子表单01',
|
||||
name: 'sub-form1',
|
||||
debug: true,
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
id: 'form_001_form_01_text_01',
|
||||
label: '名称',
|
||||
name: 'name',
|
||||
disabled: false,
|
||||
mode: 'horizontal'
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
id: 'form_001_form_01_text_02',
|
||||
label: '等级',
|
||||
name: 'level',
|
||||
disabled: false,
|
||||
mode: 'horizontal'
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
id: 'form_001_form_01_text_03',
|
||||
label: '昵称',
|
||||
name: 'myname',
|
||||
disabled: false,
|
||||
mode: 'horizontal'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
293
examples/components/EventAction/Common.jsx
Normal file
293
examples/components/EventAction/Common.jsx
Normal file
@ -0,0 +1,293 @@
|
||||
export default {
|
||||
type: 'page',
|
||||
title: '触发通用动作',
|
||||
regions: ['body', 'toolbar', 'header'],
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_001',
|
||||
label: '发送Ajax请求',
|
||||
actionType: 'reload',
|
||||
dialog: {
|
||||
title: '系统提示',
|
||||
body: '对你点击了'
|
||||
},
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm',
|
||||
messages: {
|
||||
success: '成功了!欧耶',
|
||||
failed: '失败了呢。。'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_002',
|
||||
className: 'ml-2',
|
||||
label: '打开一个弹窗',
|
||||
actionType: 'reload',
|
||||
dialog: {
|
||||
title: '系统提示',
|
||||
body: '对你点击了'
|
||||
},
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'dialog',
|
||||
args: {
|
||||
id: '${event.data.ajax1.id}'
|
||||
},
|
||||
dialog: {
|
||||
type: 'dialog',
|
||||
id: 'dialog_1',
|
||||
title: '弹框标题1',
|
||||
data: {
|
||||
id: '${id}'
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
debug: true,
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '<p>对,你刚刚点击了111${id}</p>',
|
||||
inline: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_003',
|
||||
label: '关闭一个弹窗',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
type: 'dialog',
|
||||
id: 'dialog_1',
|
||||
title: '弹框标题1',
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '<p>对,你刚刚点击了111</p>',
|
||||
inline: false
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
label: '打开一个子弹窗,然后关闭它的父亲',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
type: 'dialog',
|
||||
title: '弹框标题3',
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
label: '关闭指定弹窗',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'closeDialog',
|
||||
componentId: 'dialog_1'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
label: '关闭当前弹窗',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'closeDialog'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
label: '文本',
|
||||
name: 'text',
|
||||
disabled: false,
|
||||
mode: 'horizontal'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_004',
|
||||
label: '打开页面',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'url',
|
||||
url: 'http://www.baidu.com',
|
||||
blank: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_005',
|
||||
label: '打开页面(单页模式)',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'link',
|
||||
link: './broadcat'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_006',
|
||||
label: '弹个提示对话框',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'alert',
|
||||
msg: '该吃饭了~'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_007',
|
||||
label: '弹个确认对话框',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'confirm',
|
||||
title: '操作确认',
|
||||
msg: '要删除它吗?'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_008',
|
||||
label: '全局消息提示',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'toast',
|
||||
msgType: 'warning',
|
||||
msg: '我是一个全局警告消息',
|
||||
options: {
|
||||
position: 'top-right'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_009',
|
||||
label: '复制一段文本',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'copy',
|
||||
content: 'http://www.baidu.com'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_010',
|
||||
label: '复制一段富文本',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'copy',
|
||||
copyFormat: 'text/html',
|
||||
content: "<a href='http://www.baidu.com'>link</a> <b>bold</b>"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_011',
|
||||
label: '发送邮件',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'email',
|
||||
to: 'amis@baidu.com',
|
||||
cc: 'baidu@baidu.com',
|
||||
subject: '这是邮件主题',
|
||||
body: '这是邮件正文'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
23
examples/components/EventAction/Custom.jsx
Normal file
23
examples/components/EventAction/Custom.jsx
Normal file
@ -0,0 +1,23 @@
|
||||
export default {
|
||||
type: 'page',
|
||||
title: '自定义JS',
|
||||
regions: ['body', 'toolbar', 'header'],
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
label: '发送个请求',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
script:
|
||||
"doAction({actionType: 'ajax',api: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm'});\n //event.stopPropagation();"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
111
examples/components/EventAction/DataFlow.jsx
Normal file
111
examples/components/EventAction/DataFlow.jsx
Normal file
@ -0,0 +1,111 @@
|
||||
export default {
|
||||
type: 'page',
|
||||
title: '数据传递',
|
||||
regions: ['body', 'toolbar', 'header'],
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '<p>从事件触发开始,整个数据流包含事件本身产生的事件数据和动作产生的动作数据,事件源头产生的数据在AMIS事件动作机制底层已经自动加入渲染器数据域,可以通过"event.data.xxx"直接获取,而部分动作产生的数据如何流动需要交互设计者进行介入,对于数据流动可以通过数据映射,将上一个动作产生的数据作为动作参数写入下一个动作。通过outputVar指定输出的变量名,通过args指定输入的参数数据</p>'
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_001',
|
||||
label: '发一个广播,携带args参数',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'broadcast',
|
||||
eventName: 'broadcast_1',
|
||||
args: {
|
||||
name: 'lvxj',
|
||||
age: 18
|
||||
},
|
||||
description: '一个按钮的点击事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_001',
|
||||
label: '发送Ajax请求,并把返回数据传给弹窗',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm',
|
||||
messages: {
|
||||
success: '成功了!欧耶',
|
||||
failed: '失败了呢。。'
|
||||
},
|
||||
outputVar: 'ajax1'
|
||||
},
|
||||
{
|
||||
actionType: 'dialog',
|
||||
args: {
|
||||
id: '${event.data.ajax1.id}'
|
||||
},
|
||||
dialog: {
|
||||
type: 'dialog',
|
||||
id: 'dialog_1',
|
||||
title: '弹框标题1',
|
||||
data: {
|
||||
id: '${id}'
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
debug: true,
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '<p>Ajax请求返回的id=${id}</p>',
|
||||
inline: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
name: 'form1',
|
||||
id: 'form_001',
|
||||
title: '表单1-监听广播并获取携带的参数',
|
||||
debug: true,
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
id: 'form_001_text_01',
|
||||
label: '年龄',
|
||||
name: 'age',
|
||||
disabled: false,
|
||||
mode: 'horizontal'
|
||||
}
|
||||
],
|
||||
data: {
|
||||
name: 'amis'
|
||||
},
|
||||
onEvent: {
|
||||
broadcast_1: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'reload',
|
||||
args: {
|
||||
age: '${event.data.age}'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
191
examples/components/EventAction/Logic.jsx
Normal file
191
examples/components/EventAction/Logic.jsx
Normal file
@ -0,0 +1,191 @@
|
||||
export default {
|
||||
type: 'page',
|
||||
title: '逻辑编排',
|
||||
regions: ['body', 'toolbar', 'header'],
|
||||
body: {
|
||||
type: 'form',
|
||||
data: {
|
||||
loopData: [
|
||||
{
|
||||
name: 'lv',
|
||||
age: '19'
|
||||
},
|
||||
{
|
||||
name: 'xj',
|
||||
age: '21'
|
||||
}
|
||||
],
|
||||
branchCont: 18,
|
||||
execOn: 'kkk'
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_001',
|
||||
label: '条件',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
args: {
|
||||
param: '0'
|
||||
},
|
||||
api: 'https://api/form/ajax?param=${param}', // param=2,如果想要拿到当前域的数据需要通过args数据映射
|
||||
execOn: 'execOn === "kkk"'
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
args: {
|
||||
param: '1'
|
||||
},
|
||||
api: 'https://api/form/ajax?param=${param}', // param=2,如果想要拿到当前域的数据需要通过args数据映射
|
||||
execOn: 'execOn === "jjj"'
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
args: {
|
||||
param: '2'
|
||||
},
|
||||
api: 'https://api/form/ajax?param=${param}', // param=2,如果想要拿到当前域的数据需要通过args数据映射
|
||||
execOn: 'execOn === "kkk"'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_002',
|
||||
label: '并行',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'parallel',
|
||||
children: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/parallel-ajax-1',
|
||||
preventDefault: false
|
||||
// stopPropagation: true
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/parallel-ajax-2'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_003',
|
||||
label: '循环',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'loop',
|
||||
loopName: 'loopData',
|
||||
preventDefault: false,
|
||||
stopPropagation: false,
|
||||
args: {
|
||||
level: 3
|
||||
},
|
||||
children: [
|
||||
{
|
||||
actionType: 'reload',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/loop-ajax-1?name=${name}',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
},
|
||||
// {
|
||||
// actionType: 'break'
|
||||
// },
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/loop-ajax-2?age=${age}'
|
||||
},
|
||||
{
|
||||
actionType: 'loop',
|
||||
loopName: 'loopData',
|
||||
args: {
|
||||
level: 3
|
||||
},
|
||||
children: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/loop-loop-ajax-1'
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/loop-loop-ajax-2?age=${age}',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
},
|
||||
{
|
||||
actionType: 'continue'
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/loop-loop-ajax-3'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_004',
|
||||
label: 'switch排他',
|
||||
className: 'ml-2',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'switch',
|
||||
preventDefault: false,
|
||||
stopPropagation: false,
|
||||
children: [
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/branch-ajax-1',
|
||||
expression: 'this.branchCont > 19',
|
||||
preventDefault: false,
|
||||
stopPropagation: true // 这里无效,因为条件不成立
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/branch-ajax-2',
|
||||
expression: 'this.branchCont > 17',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
api: 'https://api/form/branch-ajax-3',
|
||||
expression: 'this.branchCont > 16'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
140
examples/components/EventAction/Stop.jsx
Normal file
140
examples/components/EventAction/Stop.jsx
Normal file
@ -0,0 +1,140 @@
|
||||
export default {
|
||||
type: 'page',
|
||||
title: '事件/动作干预',
|
||||
regions: ['body', 'toolbar', 'header'],
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_001',
|
||||
label: '联动表单1(事件干预)',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '系统提示',
|
||||
body: '对你点击了'
|
||||
},
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'broadcast',
|
||||
eventName: 'broadcast_1',
|
||||
args: {
|
||||
name: 'lvxj',
|
||||
age: 18
|
||||
},
|
||||
description: '一个按钮的点击事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
id: 'b_002',
|
||||
label: '联动表单2(动作干预)',
|
||||
className: 'ml-2',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '系统提示',
|
||||
body: '对你点击了'
|
||||
},
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'broadcast',
|
||||
eventName: 'broadcast_1',
|
||||
args: {
|
||||
name: 'lvxj',
|
||||
age: 18
|
||||
},
|
||||
description: '一个按钮的点击事件'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
type: 'form',
|
||||
name: 'form1',
|
||||
id: 'form_001',
|
||||
title: '表单1-刷新(刷新后,按钮的弹窗动作因为被干预,不会执行)',
|
||||
debug: true,
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
id: 'form_001_text_01',
|
||||
label: '年龄',
|
||||
name: 'age',
|
||||
disabled: false,
|
||||
mode: 'horizontal'
|
||||
}
|
||||
],
|
||||
data: {
|
||||
execOn: 'kkk',
|
||||
param: '1'
|
||||
},
|
||||
onEvent: {
|
||||
broadcast_1: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'reload',
|
||||
args: {
|
||||
age: '${event.data.age}'
|
||||
},
|
||||
preventDefault: true, // 阻止按钮的弹窗
|
||||
execOn: 'execOn === "kkk"' // or this.xxx
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
name: 'form2',
|
||||
id: 'form_002',
|
||||
title: '表单2-刷新+发Ajax(只执行刷新,Ajax请求被干预,不会执行)',
|
||||
debug: true,
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
id: 'form_001_text_01',
|
||||
label: '年龄',
|
||||
name: 'age',
|
||||
disabled: false,
|
||||
mode: 'horizontal'
|
||||
}
|
||||
],
|
||||
data: {
|
||||
execOn: 'kkk',
|
||||
param: '1'
|
||||
},
|
||||
onEvent: {
|
||||
broadcast_1: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'reload',
|
||||
args: {
|
||||
age: '${event.data.age}'
|
||||
},
|
||||
preventDefault: false, // 阻止按钮的弹窗
|
||||
stopPropagation: true,
|
||||
execOn: 'execOn === "kkk"' // or this.xxx
|
||||
},
|
||||
{
|
||||
actionType: 'ajax',
|
||||
args: {
|
||||
param: '2'
|
||||
},
|
||||
api: 'https://api/form/ajax?param=${param}', // param=2,如果想要拿到当前域的数据需要通过args数据映射
|
||||
execOn: 'execOn === "kkk"',
|
||||
preventDefault: false,
|
||||
stopPropagation: false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
@ -66,7 +66,13 @@ import CRUDLinkPageSchema from './Linkage/CRUD';
|
||||
import OptionsPageSchema from './Linkage/Options';
|
||||
import OptionsLocalPageSchema from './Linkage/OptionsLocal';
|
||||
import FormSubmitSchema from './Linkage/FormSubmit';
|
||||
import EventsSchema from './Linkage/Event';
|
||||
import CommonEventActionSchema from './EventAction/Common';
|
||||
import BroadcastEventActionSchema from './EventAction/Broadcast';
|
||||
import CmptEventActionSchema from './EventAction/Cmpt';
|
||||
import CustomEventActionSchema from './EventAction/Custom';
|
||||
import LogicEventActionSchema from './EventAction/Logic';
|
||||
import StopEventActionSchema from './EventAction/Stop';
|
||||
import DataFlowEventActionSchema from './EventAction/DataFlow';
|
||||
import WizardSchema from './Wizard';
|
||||
import ChartSchema from './Chart';
|
||||
import EChartsEditorSchema from './ECharts';
|
||||
@ -496,11 +502,48 @@ export const examples = [
|
||||
label: '表单和列表联动',
|
||||
path: '/examples/linkpage/crud',
|
||||
component: makeSchemaRenderer(CRUDLinkPageSchema)
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
label: '事件动作机制',
|
||||
icon: 'fa fa-bolt',
|
||||
children: [
|
||||
{
|
||||
label: '执行通用动作',
|
||||
path: '/examples/event-action/common',
|
||||
component: makeSchemaRenderer(CommonEventActionSchema)
|
||||
},
|
||||
{
|
||||
label: '广播事件机制',
|
||||
path: '/examples/linkpage/event',
|
||||
component: makeSchemaRenderer(EventsSchema)
|
||||
label: '广播(自定义事件)',
|
||||
path: '/examples/event-action/broadcat',
|
||||
component: makeSchemaRenderer(BroadcastEventActionSchema)
|
||||
},
|
||||
{
|
||||
label: '执行其他组件动作',
|
||||
path: '/examples/event-action/cmpt',
|
||||
component: makeSchemaRenderer(CmptEventActionSchema)
|
||||
},
|
||||
{
|
||||
label: '自定义JS',
|
||||
path: '/examples/event-action/custom',
|
||||
component: makeSchemaRenderer(CustomEventActionSchema)
|
||||
},
|
||||
{
|
||||
label: '执行逻辑编排动作',
|
||||
path: '/examples/event-action/logic',
|
||||
component: makeSchemaRenderer(LogicEventActionSchema)
|
||||
},
|
||||
{
|
||||
label: '事件/动作干预',
|
||||
path: '/examples/event-action/stop',
|
||||
component: makeSchemaRenderer(StopEventActionSchema)
|
||||
},
|
||||
{
|
||||
label: '动作间数据传递',
|
||||
path: '/examples/event-action/dataflow',
|
||||
component: makeSchemaRenderer(DataFlowEventActionSchema)
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -65,7 +65,7 @@ class BroadcastCmpt extends React.Component<BroadcastCmptProps> {
|
||||
|
||||
constructor(props: BroadcastCmptProps, context: IScopedContext) {
|
||||
super(props);
|
||||
this.triggerEvent = this.triggerEvent.bind(this);
|
||||
this.dispatchEvent = this.dispatchEvent.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -81,7 +81,7 @@ class BroadcastCmpt extends React.Component<BroadcastCmptProps> {
|
||||
return this.ref;
|
||||
}
|
||||
|
||||
async triggerEvent(
|
||||
async dispatchEvent(
|
||||
e: React.MouseEvent<any>,
|
||||
data: any
|
||||
): Promise<RendererEvent<any> | undefined> {
|
||||
@ -108,10 +108,10 @@ class BroadcastCmpt extends React.Component<BroadcastCmptProps> {
|
||||
<Component
|
||||
ref={this.childRef}
|
||||
{...rest}
|
||||
dispatchEvent={this.triggerEvent}
|
||||
dispatchEvent={this.dispatchEvent}
|
||||
/>
|
||||
) : (
|
||||
<Component {...rest} dispatchEvent={this.triggerEvent} />
|
||||
<Component {...rest} dispatchEvent={this.dispatchEvent} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ export interface ListenerAction {
|
||||
description?: string; // 事件描述,actionType: broadcast
|
||||
componentId?: string; // 组件ID,用于直接执行指定组件的动作
|
||||
args?: any; // 参数,可以配置数据映射
|
||||
outputVar?: any; // 输出数据变量名
|
||||
preventDefault?: boolean; // 阻止原有组件的动作行为
|
||||
stopPropagation?: boolean; // 阻止后续的事件处理器执行
|
||||
execOn?: string; // 执行条件
|
||||
@ -72,7 +73,7 @@ export const runActions = async (
|
||||
let actionInstrance = getActionByType(actionConfig.actionType);
|
||||
|
||||
// 如果存在指定组件ID,说明是组件专有动作
|
||||
if (actionConfig.componentId) {
|
||||
if (!actionInstrance && actionConfig.componentId) {
|
||||
actionInstrance = getActionByType('component');
|
||||
} else if (
|
||||
actionConfig.actionType === 'url' ||
|
||||
@ -80,7 +81,7 @@ export const runActions = async (
|
||||
actionConfig.actionType === 'jump'
|
||||
) {
|
||||
// 打开页面动作
|
||||
actionInstrance = getActionByType('openpage');
|
||||
actionInstrance = getActionByType('openlink');
|
||||
}
|
||||
|
||||
// 找不到就通过组件专有动作完成
|
||||
|
@ -1,5 +1,8 @@
|
||||
import {IRootStore} from '../store/root';
|
||||
import {isVisible} from '../utils/helper';
|
||||
import {fetchOptions} from '../types';
|
||||
import {normalizeApiResponseData} from '../utils/api';
|
||||
import {ServerError} from '../utils/errors';
|
||||
import {createObject, isEmpty, isVisible} from '../utils/helper';
|
||||
import {RendererEvent} from '../utils/renderer-event';
|
||||
import {filter} from '../utils/tpl';
|
||||
import {
|
||||
@ -22,36 +25,73 @@ export class AjaxAction implements Action {
|
||||
renderer: ListenerContext,
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
const store = renderer.props.store;
|
||||
const env = event.context.env;
|
||||
try {
|
||||
const options = {
|
||||
...(action.options ?? {}),
|
||||
method: action.method ?? 'post'
|
||||
};
|
||||
|
||||
store.setCurrentAction(action);
|
||||
store
|
||||
.saveRemote(action.api as string, action.args, {
|
||||
successMessage: action.messages && action.messages.success,
|
||||
errorMessage: action.messages && action.messages.failed
|
||||
})
|
||||
.then(async () => {
|
||||
if (action.feedback && isVisible(action.feedback, store.data)) {
|
||||
await this.openFeedback(action.feedback, store);
|
||||
}
|
||||
const result = await env.fetcher(
|
||||
action.api as string,
|
||||
action.args,
|
||||
options
|
||||
);
|
||||
|
||||
const redirect = action.redirect && filter(action.redirect, store.data);
|
||||
redirect && renderer.env.jumpTo(redirect, action);
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
if (!isEmpty(result.data) || result.ok) {
|
||||
const responseData = normalizeApiResponseData(result.data);
|
||||
// 记录请求返回的数据
|
||||
event.setData(
|
||||
createObject(
|
||||
event.data,
|
||||
action.outputVar
|
||||
? {
|
||||
[`${action.outputVar}`]: responseData
|
||||
}
|
||||
: responseData
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
openFeedback(dialog: any, store: IRootStore) {
|
||||
return new Promise(resolve => {
|
||||
store.setCurrentAction({
|
||||
type: 'button',
|
||||
actionType: 'dialog',
|
||||
dialog: dialog
|
||||
});
|
||||
store.openDialog(store.data, undefined, confirmed => {
|
||||
resolve(confirmed);
|
||||
});
|
||||
});
|
||||
if (!result.ok) {
|
||||
throw new ServerError(
|
||||
(action.messages && action.messages.failed) ?? result.msg,
|
||||
result
|
||||
);
|
||||
} else {
|
||||
env.notify(
|
||||
'success',
|
||||
(action.messages && action.messages.success) ?? result.msg,
|
||||
result.msgTimeout !== undefined
|
||||
? {
|
||||
closeButton: true,
|
||||
timeout: result.msgTimeout
|
||||
}
|
||||
: undefined
|
||||
);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
} catch (e) {
|
||||
if (e.type === 'ServerError') {
|
||||
const result = (e as ServerError).response;
|
||||
env.notify(
|
||||
'error',
|
||||
e.message,
|
||||
result.msgTimeout !== undefined
|
||||
? {
|
||||
closeButton: true,
|
||||
timeout: result.msgTimeout
|
||||
}
|
||||
: undefined
|
||||
);
|
||||
} else {
|
||||
env.notify('error', e.message);
|
||||
}
|
||||
|
||||
// 不阻塞后面执行
|
||||
// throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ export class BroadcastAction implements Action {
|
||||
return await event.context.env.dispatchEvent(
|
||||
action.eventName,
|
||||
renderer,
|
||||
event.context.scoped,
|
||||
action.args,
|
||||
event
|
||||
);
|
||||
|
@ -23,13 +23,18 @@ export class CmptAction implements Action {
|
||||
) {
|
||||
// 根据唯一ID查找指定组件
|
||||
const component =
|
||||
renderer.props.$schema.id !== action.componentId
|
||||
action.componentId && renderer.props.$schema.id !== action.componentId
|
||||
? event.context.scoped?.getComponentById(action.componentId)
|
||||
: renderer;
|
||||
|
||||
// 执行组件动作
|
||||
(await component.props.onAction?.(event, action, action.args)) ||
|
||||
component.doAction?.(action, action.args);
|
||||
return (
|
||||
(await component.props.onAction?.(
|
||||
event.context.nativeEvent,
|
||||
action,
|
||||
action.args
|
||||
)) || component.doAction?.(action, action.args)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ export class CopyAction implements Action {
|
||||
renderer: ListenerContext,
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
debugger;
|
||||
if (action.content || action.copy) {
|
||||
renderer.props.env.copy?.(
|
||||
filter(action.content || action.copy, action.args, '| raw'),
|
||||
|
@ -37,8 +37,10 @@ export class CustomAction implements Action {
|
||||
await (scriptFunc as any)?.call(
|
||||
null,
|
||||
renderer,
|
||||
renderer.doAction.bind(renderer),
|
||||
event
|
||||
renderer.props.onAction?.bind(renderer, event.context.nativeEvent) ||
|
||||
renderer.doAction?.bind(renderer),
|
||||
event,
|
||||
action
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
import React from 'react';
|
||||
import {render} from 'react-dom';
|
||||
import {render as amisRender} from '../factory';
|
||||
import {uuid} from '../utils/helper';
|
||||
import {RendererEvent} from '../utils/renderer-event';
|
||||
import {
|
||||
Action,
|
||||
@ -6,6 +10,12 @@ import {
|
||||
registerAction
|
||||
} from './Action';
|
||||
|
||||
let dialogs: {
|
||||
id: string;
|
||||
action: any;
|
||||
store: any;
|
||||
}[] = [];
|
||||
|
||||
/**
|
||||
* 打开弹窗动作
|
||||
*
|
||||
@ -20,9 +30,68 @@ export class DialogAction implements Action {
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
const store = renderer.props.store;
|
||||
// 记录弹窗
|
||||
dialogs.push({
|
||||
id: action.dialog.id || '', // id依赖用户的配置
|
||||
action,
|
||||
store
|
||||
});
|
||||
// 打开弹窗
|
||||
store.setCurrentAction(action);
|
||||
store.openDialog(action.args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭弹窗动作
|
||||
*
|
||||
* @export
|
||||
* @class CloseDialogAction
|
||||
* @implements {Action}
|
||||
*/
|
||||
export class CloseDialogAction implements Action {
|
||||
async run(
|
||||
action: ListenerAction,
|
||||
renderer: ListenerContext,
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
// 找到指定关闭的弹窗或者直接关闭当前
|
||||
const context = action.componentId
|
||||
? dialogs.find(item => item.id === action.componentId)
|
||||
: dialogs[dialogs.length - 1];
|
||||
// 如果通过store去关闭,需要确保store是dialog的渲染载体
|
||||
// 但如果是弹窗里弹窗的话,关闭父弹窗会同时关闭子弹窗
|
||||
context?.store.closeDialog(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* alert提示动作
|
||||
*/
|
||||
export class AlertAction implements Action {
|
||||
async run(
|
||||
action: ListenerAction,
|
||||
renderer: ListenerContext,
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
event.context.env.alert?.(action.msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* confirm确认提示动作
|
||||
*/
|
||||
export class ConfirmAction implements Action {
|
||||
async run(
|
||||
action: ListenerAction,
|
||||
renderer: ListenerContext,
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
event.context.env.confirm?.(action.msg, action.title);
|
||||
}
|
||||
}
|
||||
|
||||
registerAction('dialog', new DialogAction());
|
||||
registerAction('closeDialog', new CloseDialogAction());
|
||||
registerAction('alert', new AlertAction());
|
||||
registerAction('confirm', new ConfirmAction());
|
||||
|
@ -1,28 +1,23 @@
|
||||
import {RendererEvent} from '../utils/renderer-event';
|
||||
import {
|
||||
Action,
|
||||
ListenerAction,
|
||||
ListenerContext,
|
||||
registerAction
|
||||
} from './Action';
|
||||
import {registerAction} from './Action';
|
||||
import {CloseDialogAction, DialogAction} from './DialogAction';
|
||||
|
||||
/**
|
||||
* 打开抽屉动作
|
||||
*
|
||||
* @export
|
||||
* @class DrawerAction
|
||||
* @implements {Action}
|
||||
* @extends {DialogAction}
|
||||
*/
|
||||
export class DrawerAction implements Action {
|
||||
async run(
|
||||
action: ListenerAction,
|
||||
renderer: ListenerContext,
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
const store = renderer.props.store;
|
||||
store.setCurrentAction(action);
|
||||
store.openDrawer(action.args);
|
||||
}
|
||||
}
|
||||
export class DrawerAction extends DialogAction {}
|
||||
|
||||
/**
|
||||
* 关闭抽屉动作
|
||||
*
|
||||
* @export
|
||||
* @class CloseDrawerAction
|
||||
* @extends {CloseDialogAction}
|
||||
*/
|
||||
export class CloseDrawerAction extends CloseDialogAction {}
|
||||
|
||||
registerAction('drawer', new DrawerAction());
|
||||
registerAction('closeDrawer', new CloseDrawerAction());
|
||||
|
@ -11,10 +11,10 @@ import {
|
||||
* 打开页面动作
|
||||
*
|
||||
* @export
|
||||
* @class OpenPageAction
|
||||
* @class LinkAction
|
||||
* @implements {Action}
|
||||
*/
|
||||
export class OpenPageAction implements Action {
|
||||
export class LinkAction implements Action {
|
||||
async run(
|
||||
action: ListenerAction,
|
||||
renderer: ListenerContext,
|
||||
@ -36,4 +36,4 @@ export class OpenPageAction implements Action {
|
||||
}
|
||||
}
|
||||
|
||||
registerAction('openpage', new OpenPageAction());
|
||||
registerAction('openlink', new LinkAction());
|
22
src/actions/ToastAction.ts
Normal file
22
src/actions/ToastAction.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import {RendererEvent} from '../utils/renderer-event';
|
||||
import {
|
||||
Action,
|
||||
ListenerAction,
|
||||
ListenerContext,
|
||||
registerAction
|
||||
} from './Action';
|
||||
|
||||
/**
|
||||
* 全局toast
|
||||
*/
|
||||
export class ToastAction implements Action {
|
||||
async run(
|
||||
action: ListenerAction,
|
||||
renderer: ListenerContext,
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
event.context.env.notify?.(action.msgType, action.msg, action.options);
|
||||
}
|
||||
}
|
||||
|
||||
registerAction('toast', new ToastAction());
|
@ -15,6 +15,7 @@ import './CopyAction';
|
||||
import './DialogAction';
|
||||
import './DrawerAction';
|
||||
import './EmailAction';
|
||||
import './OpenPageAction';
|
||||
import './LinkAction';
|
||||
import './ToastAction';
|
||||
|
||||
export * from './Action';
|
||||
|
@ -381,7 +381,7 @@ const defaultOptions: RenderOptions = {
|
||||
|
||||
return () => {
|
||||
this.rendererEventListeners = this.rendererEventListeners.filter(
|
||||
(item: RendererEventListener) => item.renderer === renderer
|
||||
(item: RendererEventListener) => item.renderer !== renderer
|
||||
);
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user