feat:scoped支持调用amis动作 (#8875)

This commit is contained in:
hsm-lv 2023-11-23 19:37:07 +08:00 committed by GitHub
parent a60d174037
commit 7d4776e78a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 9 deletions

View File

@ -230,6 +230,59 @@ let amisScoped = amis.embed(
还可以通过 `amisScoped.getComponentByName('page1.form1').setValues({'name1': 'othername'})` 来修改表单中的值。
### 调用 amis 动作
可以通过`amisScoped.doAction(actions, ctx)`来调用 amis 中的通用动作和目标组件的动作。了解事件动作机制可以查看[事件动作](../../docs/concepts/event-action)。参数说明如下:
- `actions`:动作列表,支持执行单个或多个动作
- `ctx`:上下文,它可以为动作配置补充上下文数据,例如下面`toast`动作中`msg`配置中的`${myName}`就来自于补充上下文`ctx`
下面的例子中依次执行了`toast提示`、`ajax请求`、`dialog弹窗`、`给目标组件赋值`动作。
```js
amisScoped.doAction(
[
{
actionType: 'toast',
args: {
msg: '${amisUser.name}, ${myName}'
}
},
{
actionType: 'ajax',
api: {
url: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm',
method: 'post'
}
},
{
actionType: 'dialog',
dialog: {
type: 'dialog',
title: '弹窗',
body: [
{
type: 'tpl',
tpl: '<p>对,你打开了弹窗</p>',
inline: false
}
]
}
},
{
actionType: 'setValue',
componentId: 'name',
args: {
value: '${myName}'
}
}
],
{
myName: 'amis'
}
);
```
### 更新属性
可以通过 amisScoped 对象的 updateProps 方法来更新下发到 amis 的属性。

View File

@ -21,7 +21,8 @@ import {
} from './utils/helper';
import {RendererData, ActionObject} from './types';
import {isPureVariable} from './utils/isPureVariable';
import {filter} from './utils';
import {createObject, createRendererEvent, filter} from './utils';
import {ListenerAction, runActions} from './actions';
/**
* target ?xxx=xxx ?xxx=xxx filter
@ -75,6 +76,7 @@ export interface IScopedContext {
session: string,
path: string
) => ScopedComponentType[];
doAction: (actions: ListenerAction | ListenerAction[], ctx: any) => void;
}
type AliasIScopedContext = IScopedContext;
@ -355,6 +357,22 @@ function createScopedTools(
if (component && component.props.show) {
closeDialog(component);
}
},
async doAction(actions: ListenerAction | ListenerAction[], ctx: any) {
const renderer = this.getComponents()[0]; // 直接拿最顶层
const rendererEvent = createRendererEvent('embed', {
env,
nativeEvent: undefined,
data: createObject(renderer.props.data, ctx),
scoped: this
});
await runActions(actions, renderer, rendererEvent);
if (rendererEvent.prevented) {
return;
}
}
};

View File

@ -39,7 +39,7 @@ export class AjaxAction implements RendererAction {
renderer: ListenerContext,
event: RendererEvent<any>
) {
if (!renderer.props.env?.fetcher) {
if (!event.context.env?.fetcher) {
throw new Error('env.fetcher is required!');
}

View File

@ -40,7 +40,7 @@ export class CmptAction implements RendererAction {
/** 如果args中携带path参数, 则认为是全局变量赋值, 否则认为是组件变量赋值 */
if (action.actionType === 'setValue' && path && typeof path === 'string') {
const beforeSetData = renderer?.props?.env?.beforeSetData;
const beforeSetData = event?.context?.env?.beforeSetData;
if (beforeSetData && typeof beforeSetData === 'function') {
const res = await beforeSetData(renderer, action, event);

View File

@ -28,12 +28,12 @@ export class CopyAction implements RendererAction {
renderer: ListenerContext,
event: RendererEvent<any>
) {
if (!renderer.props.env?.copy) {
if (!event.context.env?.copy) {
throw new Error('env.copy is required!');
}
if (action.args?.content) {
renderer.props.env.copy?.(action.args.content, {
event.context.env?.copy?.(action.args.content, {
format: action.args?.copyFormat ?? 'text/html'
});
}

View File

@ -34,7 +34,7 @@ export class LinkAction implements RendererAction {
renderer: ListenerContext,
event: RendererEvent<any>
) {
if (!renderer.props.env?.jumpTo) {
if (!event.context.env?.jumpTo) {
throw new Error('env.jumpTo is required!');
}
@ -53,7 +53,7 @@ export class LinkAction implements RendererAction {
}
);
renderer.props.env.jumpTo(
event.context.env?.jumpTo(
urlObj.url,
{
actionType: action.actionType,

View File

@ -34,11 +34,11 @@ export class ToastAction implements RendererAction {
renderer: ListenerContext,
event: RendererEvent<any>
) {
if (!renderer.props.env?.notify) {
if (!event.context.env?.notify) {
throw new Error('env.notify is required!');
}
event.context.env.notify?.(
event.context.env?.notify?.(
action.args?.msgType || 'info',
String(action.args?.msg),
action.args