mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: 支持全局广播事件
This commit is contained in:
parent
82efeba01d
commit
18f7087406
@ -26,7 +26,12 @@ import {
|
||||
formateId
|
||||
} from './utils/helper';
|
||||
import {SimpleMap} from './utils/SimpleMap';
|
||||
import {bindEvent, dispatchEvent, RendererEvent} from './utils/renderer-event';
|
||||
import {
|
||||
bindEvent,
|
||||
bindGlobalEvent,
|
||||
dispatchEvent,
|
||||
RendererEvent
|
||||
} from './utils/renderer-event';
|
||||
import {isAlive} from 'mobx-state-tree';
|
||||
import {reaction} from 'mobx';
|
||||
import {resolveVariableAndFilter} from './utils/tpl-builtin';
|
||||
@ -110,6 +115,7 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
||||
|
||||
toDispose: Array<() => any> = [];
|
||||
unbindEvent: (() => void) | undefined = undefined;
|
||||
unbindGlobalEvent: (() => void) | undefined = undefined;
|
||||
isStatic: any = undefined;
|
||||
|
||||
constructor(props: SchemaRendererProps) {
|
||||
@ -175,6 +181,7 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
||||
this.toDispose.forEach(fn => fn());
|
||||
this.toDispose = [];
|
||||
this.unbindEvent?.();
|
||||
this.unbindGlobalEvent?.();
|
||||
this.removeAnimationStyle();
|
||||
}
|
||||
|
||||
@ -299,7 +306,10 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
||||
if (ref) {
|
||||
// 这里无法区分监听的是不是广播,所以又bind一下,主要是为了绑广播
|
||||
this.unbindEvent?.();
|
||||
this.unbindGlobalEvent?.();
|
||||
|
||||
this.unbindEvent = bindEvent(ref);
|
||||
this.unbindGlobalEvent = bindGlobalEvent(ref);
|
||||
}
|
||||
this.cRef = ref;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {RendererProps} from '../factory';
|
||||
import {createObject} from '../utils/helper';
|
||||
import {RendererEvent, dispatchEvent} from '../utils/renderer-event';
|
||||
import {RendererEvent, dispatchGlobalEvent} from '../utils/renderer-event';
|
||||
import {
|
||||
RendererAction,
|
||||
ListenerAction,
|
||||
@ -37,14 +37,17 @@ export class BroadcastAction implements RendererAction {
|
||||
// 作为一个新的事件,需要把广播动作的args参数追加到事件数据中
|
||||
event.setData(createObject(event.data, action.data ?? {}));
|
||||
|
||||
const eventName = action.args?.eventName || action.eventName!;
|
||||
|
||||
return await dispatchGlobalEvent(eventName, action.data);
|
||||
// 直接触发对应的动作
|
||||
return await dispatchEvent(
|
||||
action.args?.eventName || action.eventName!,
|
||||
renderer,
|
||||
event.context.scoped,
|
||||
action.data,
|
||||
event
|
||||
);
|
||||
// return await dispatchEvent(
|
||||
// action.args?.eventName || action.eventName!,
|
||||
// renderer,
|
||||
// event.context.scoped,
|
||||
// action.data,
|
||||
// event
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,48 @@ export const bindEvent = (renderer: any) => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const bindGlobalEvent = (renderer: any) => {
|
||||
if (!renderer) {
|
||||
return undefined;
|
||||
}
|
||||
const listeners: EventListeners = renderer.props.$schema.onEvent;
|
||||
let bcs: Array<{
|
||||
renderer: any;
|
||||
bc: BroadcastChannel;
|
||||
}> = [];
|
||||
if (listeners) {
|
||||
for (let key of Object.keys(listeners)) {
|
||||
const listener = listeners[key];
|
||||
if (!BroadcastChannel) {
|
||||
console.error('BroadcastChannel is not supported in your browser');
|
||||
return;
|
||||
}
|
||||
const bc = new BroadcastChannel(key);
|
||||
bcs.push({
|
||||
renderer: renderer,
|
||||
bc
|
||||
});
|
||||
bc.onmessage = e => {
|
||||
const {eventName, data} = e.data;
|
||||
const rendererEvent = createRendererEvent(eventName, {
|
||||
env: renderer?.props?.env,
|
||||
nativeEvent: eventName,
|
||||
scoped: renderer?.context,
|
||||
data
|
||||
});
|
||||
|
||||
runActions(listener.actions, renderer, rendererEvent);
|
||||
};
|
||||
}
|
||||
return () => {
|
||||
bcs
|
||||
.filter(item => item.renderer === renderer)
|
||||
.forEach(item => item.bc.close());
|
||||
};
|
||||
}
|
||||
return void 0;
|
||||
};
|
||||
|
||||
// 触发事件
|
||||
export async function dispatchEvent(
|
||||
e: string | React.MouseEvent<any>,
|
||||
@ -313,6 +355,19 @@ export async function dispatchEvent(
|
||||
return Promise.resolve(rendererEvent);
|
||||
}
|
||||
|
||||
export async function dispatchGlobalEvent(eventName: string, data: any) {
|
||||
if (!BroadcastChannel) {
|
||||
console.error('BroadcastChannel is not supported in your browser');
|
||||
return;
|
||||
}
|
||||
|
||||
const bc = new BroadcastChannel(eventName);
|
||||
bc.postMessage({
|
||||
eventName,
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
export const getRendererEventListeners = () => {
|
||||
return rendererEventListeners;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user