63 lines
2.2 KiB
JavaScript
63 lines
2.2 KiB
JavaScript
export const TreeLoadChildrenMixin = (superClass) => class TreeLoadChildrenMixin extends superClass {
|
|
async _loadChildrenForExpanded(key, source, originalEvent, nodeHint = null, pathHint = null) {
|
|
if (typeof this.loadChildren !== 'function') return;
|
|
|
|
const node = nodeHint ?? this._findNodeByKey(key);
|
|
if (!node) return;
|
|
|
|
const controller = new AbortController();
|
|
const seq = ++this._childLoadSeq;
|
|
const previous = this._childLoadControllers.get(key);
|
|
if (previous) {
|
|
try { previous.abort(); } catch (e) { }
|
|
}
|
|
this._childLoadControllers.set(key, controller);
|
|
|
|
this._updateNodeStatesByKey(key, (n) => {
|
|
const states = Array.isArray(n.states) ? n.states : [];
|
|
const next = states.filter((s) => s !== 'loaded');
|
|
if (!next.includes('loading')) next.push('loading');
|
|
return { ...n, states: next };
|
|
});
|
|
|
|
try {
|
|
const ctx = {
|
|
node,
|
|
key,
|
|
path: Array.isArray(pathHint) ? pathHint : key.split('/').filter(Boolean),
|
|
signal: controller.signal,
|
|
source,
|
|
originalEvent,
|
|
};
|
|
|
|
await Promise.resolve(this.loadChildren(ctx));
|
|
if (controller.signal.aborted) return;
|
|
if (this._childLoadControllers.get(key) !== controller) return;
|
|
if (seq !== this._childLoadSeq) return;
|
|
|
|
this._updateNodeStatesByKey(key, (n) => {
|
|
const states = Array.isArray(n.states) ? n.states : [];
|
|
const next = states.filter((s) => s !== 'loading');
|
|
if (!next.includes('loaded')) next.push('loaded');
|
|
return { ...n, states: next };
|
|
});
|
|
} catch (err) {
|
|
if (controller.signal.aborted) return;
|
|
this._updateNodeStatesByKey(key, (n) => {
|
|
const states = Array.isArray(n.states) ? n.states : [];
|
|
const next = states.filter((s) => s !== 'loading');
|
|
return { ...n, states: next };
|
|
});
|
|
this.dispatchEvent(new CustomEvent('node-children-error', {
|
|
detail: { key, node, error: err, source, originalEvent },
|
|
bubbles: true,
|
|
composed: true,
|
|
}));
|
|
} finally {
|
|
if (this._childLoadControllers.get(key) === controller) {
|
|
this._childLoadControllers.delete(key);
|
|
}
|
|
}
|
|
}
|
|
};
|