feat: 支持全局事件动作

This commit is contained in:
yupeng12 2024-11-06 17:12:26 +08:00
parent 82efeba01d
commit 05cce06b80
4 changed files with 102 additions and 1 deletions

View File

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

View File

@ -0,0 +1,46 @@
/**
* @file GlobalEventAction.ts
*
* @created: 2024/11/05
*/
import {createObject} from '../utils/helper';
import {RendererEvent, dispatchGlobalEvent} from '../utils/renderer-event';
import {
registerAction,
RendererAction,
ListenerAction,
ListenerContext
} from './Action';
export interface IGlobalEventAction extends ListenerAction {
actionType: string;
}
/**
* GlobalEventAction
*
* @export
* @class GlobalEventAction
* @implements {RendererAction}
*/
export class GlobalEventAction implements RendererAction {
async run(
action: IGlobalEventAction,
renderer: ListenerContext,
event: RendererEvent<any>
) {
if (!action.eventName) {
console.error('eventName 未定义,请定义事件名称');
return;
}
event.setData(createObject(event.data, action.data ?? {}));
console.log(action.eventName);
// 直接触发对应的动作
return await dispatchGlobalEvent(action.eventName, action.data);
}
}
registerAction('globalEvent', new GlobalEventAction());

View File

@ -22,5 +22,6 @@ import './ToastAction';
import './WaitAction';
import './PageAction';
import './PrintAction';
import './GlobalEventAction';
export * from './Action';

View File

@ -195,6 +195,42 @@ 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 = [];
if (listeners) {
// 暂存
for (let key of Object.keys(listeners)) {
const listener = listeners[key];
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 +349,14 @@ export async function dispatchEvent(
return Promise.resolve(rendererEvent);
}
export async function dispatchGlobalEvent(eventName: string, data: any) {
const bc = new BroadcastChannel(eventName);
bc.postMessage({
eventName,
data
});
}
export const getRendererEventListeners = () => {
return rendererEventListeners;
};