feat:补充一些通用动作&完善事件动作机制示例 (#3495)

* feat:补充一些通用动作&完善事件动作机制示例

* feat:补充一些通用动作&完善事件动作机制示例
This commit is contained in:
hsm-lv 2022-01-26 09:18:48 +08:00 committed by GitHub
parent 37c5b8e673
commit 8cc8283ded
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1096 additions and 181 deletions

View File

@ -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'
}
]
}
]
}
]
},

View 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'
}
]
}
]
}
]
};

View 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: '这是邮件正文'
}
]
}
}
}
]
};

View 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();"
}
]
}
}
}
]
};

View 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}'
}
}
]
}
}
}
]
};

View 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=2args
execOn: 'execOn === "kkk"'
},
{
actionType: 'ajax',
args: {
param: '1'
},
api: 'https://api/form/ajax?param=${param}', // param=2args
execOn: 'execOn === "jjj"'
},
{
actionType: 'ajax',
args: {
param: '2'
},
api: 'https://api/form/ajax?param=${param}', // param=2args
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'
}
]
}
]
}
}
}
]
}
};

View 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=2args
execOn: 'execOn === "kkk"',
preventDefault: false,
stopPropagation: false
}
]
}
}
}
]
};

View File

@ -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)
}
]
},

View File

@ -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} />
);
}
}

View File

@ -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');
}
// 找不到就通过组件专有动作完成

View File

@ -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;
}
}
}

View File

@ -32,6 +32,7 @@ export class BroadcastAction implements Action {
return await event.context.env.dispatchEvent(
action.eventName,
renderer,
event.context.scoped,
action.args,
event
);

View File

@ -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)
);
}
}

View File

@ -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'),

View File

@ -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
);
}
}

View File

@ -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());

View File

@ -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());

View File

@ -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());

View 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());

View File

@ -15,6 +15,7 @@ import './CopyAction';
import './DialogAction';
import './DrawerAction';
import './EmailAction';
import './OpenPageAction';
import './LinkAction';
import './ToastAction';
export * from './Action';

View File

@ -381,7 +381,7 @@ const defaultOptions: RenderOptions = {
return () => {
this.rendererEventListeners = this.rendererEventListeners.filter(
(item: RendererEventListener) => item.renderer === renderer
(item: RendererEventListener) => item.renderer !== renderer
);
};
}