qwertyyb 88c04c6dac
feat: 支持数据源事件 (#605)
* feat: 添加observedData

* feat: 修改错误

* fix: 修复单测报错问题

* feat: 完善数据源事件

* fix: 修复数据源事件调用组件方法时报错的异常

* fix: 修复多个相同类型的数据源数据变化的事件混淆的问题

* chore: 删除无用代码

* feat: 默认使用SimpleObservedData

* feat: 删除无用代码

---------

Co-authored-by: marchyang <marchyang@tencent.com>
2024-05-13 17:23:23 +08:00

50 lines
1.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import State from 'deep-state-observer';
import { ObservedData } from './ObservedData';
const ignoreFirstCall = <F extends (...args: any[]) => any>(fn: F) => {
let calledTimes = 0;
return (...args: Parameters<F>) => {
if (calledTimes === 0) {
calledTimes += 1;
return;
}
return fn(...args);
};
};
export class DeepObservedData extends ObservedData {
state?: State;
subscribers = new Map<string, Map<Function, () => void>>();
constructor(initialData: Record<string, any>) {
super();
this.state = new State(initialData);
}
update = (data: any, path?: string) => {
this.state?.update(path ?? '', data);
};
on = (path: string, callback: (newVal: any) => void) => {
// subscribe 会立即执行一次ignoreFirstCall 会忽略第一次执行
const unsubscribe = this.state!.subscribe(path, ignoreFirstCall(callback));
// 把取消监听的函数保存下来,供 off 时调用
const pathSubscribers = this.subscribers.get(path) ?? new Map<Function, () => void>();
pathSubscribers.set(callback, unsubscribe);
this.subscribers.set(path, pathSubscribers);
};
off = (path: string, callback: (newVal: any) => void) => {
const pathSubscribers = this.subscribers.get(path);
if (!pathSubscribers) return;
pathSubscribers.get(callback)?.();
pathSubscribers.delete(callback);
};
getData = (path: string) => (!this.state ? {} : this.state?.get(path));
destroy = () => {
// 销毁所有未被取消的监听
this.subscribers.forEach((pathSubscribers) => {
pathSubscribers.forEach((unsubscribe) => unsubscribe());
});
};
}