From a713d9d649315044d55973db69d4d81c94654a83 Mon Sep 17 00:00:00 2001 From: lawvs <18554747+lawvs@users.noreply.github.com> Date: Thu, 25 Aug 2022 18:22:39 +0800 Subject: [PATCH] feat: async block support deep observe --- .../src/editor/block/async-block.ts | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/libs/components/editor-core/src/editor/block/async-block.ts b/libs/components/editor-core/src/editor/block/async-block.ts index 73db5de087..1bdc7ef086 100644 --- a/libs/components/editor-core/src/editor/block/async-block.ts +++ b/libs/components/editor-core/src/editor/block/async-block.ts @@ -180,9 +180,49 @@ export class AsyncBlock { return this.event_emitter.emit(eventName, eventData); } - onUpdate(callback: (event: EventData) => void) { - this.on('update', callback); + /** + * @param deep observe deep + * + * NOTICE: the observe of children is async, + * so there maybe have some delay before observe done. + */ + onUpdate(callback: (event: EventData) => void, deep = 0) { + let expired = false; + const unobserveMap: Record void> = {}; + const observeChildren = () => { + if (deep <= 0) { + return; + } + this.children().then(children => { + // Check current event listeners is not expired + if (expired) { + return; + } + children.forEach(child => { + if (unobserveMap[child.id]) return; + const unobserve = child.onUpdate(callback, deep - 1); + unobserveMap[child.id] = unobserve; + }); + }); + }; + + const unobserveChildren = () => { + Object.values(unobserveMap).forEach(unobserve => { + unobserve(); + }); + }; + + this.on('update', e => { + callback(e); + // Update children observe + observeChildren(); + }); + + observeChildren(); + return () => { + expired = true; + unobserveChildren(); this.off('update', callback); }; }