提交 cf6dc50e 编写于 作者: J Joao Moreno

fixes #84569

cc @alexr00
上级 9d19915e
...@@ -452,7 +452,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable ...@@ -452,7 +452,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
const viewStateContext = viewState && { viewState, focus: [], selection: [] } as IAsyncDataTreeViewStateContext<TInput, T>; const viewStateContext = viewState && { viewState, focus: [], selection: [] } as IAsyncDataTreeViewStateContext<TInput, T>;
await this._updateChildren(input, true, viewStateContext); await this._updateChildren(input, true, false, viewStateContext);
if (viewStateContext) { if (viewStateContext) {
this.tree.setFocus(viewStateContext.focus); this.tree.setFocus(viewStateContext.focus);
...@@ -464,11 +464,11 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable ...@@ -464,11 +464,11 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
} }
} }
async updateChildren(element: TInput | T = this.root.element, recursive = true): Promise<void> { async updateChildren(element: TInput | T = this.root.element, recursive = true, rerender = false): Promise<void> {
await this._updateChildren(element, recursive); await this._updateChildren(element, recursive, rerender);
} }
private async _updateChildren(element: TInput | T = this.root.element, recursive = true, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> { private async _updateChildren(element: TInput | T = this.root.element, recursive = true, rerender = false, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
if (typeof this.root.element === 'undefined') { if (typeof this.root.element === 'undefined') {
throw new TreeError(this.user, 'Tree input not set'); throw new TreeError(this.user, 'Tree input not set');
} }
...@@ -478,7 +478,12 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable ...@@ -478,7 +478,12 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
await Event.toPromise(this._onDidRender.event); await Event.toPromise(this._onDidRender.event);
} }
await this.refreshAndRenderNode(this.getDataNode(element), recursive, viewStateContext); const node = this.getDataNode(element);
await this.refreshAndRenderNode(node, recursive, viewStateContext);
if (rerender) {
this.tree.rerender(node);
}
} }
resort(element: TInput | T = this.root.element, recursive = true): void { resort(element: TInput | T = this.root.element, recursive = true): void {
......
...@@ -12,19 +12,28 @@ import { timeout } from 'vs/base/common/async'; ...@@ -12,19 +12,28 @@ import { timeout } from 'vs/base/common/async';
interface Element { interface Element {
id: string; id: string;
suffix?: string;
children?: Element[]; children?: Element[];
} }
function find(elements: Element[] | undefined, id: string): Element { function find(element: Element, id: string): Element | undefined {
while (elements) { if (element.id === id) {
for (const element of elements) { return element;
if (element.id === id) { }
return element;
} if (!element.children) {
return undefined;
}
for (const child of element.children) {
const result = find(child, id);
if (result) {
return result;
} }
} }
throw new Error('element not found'); return undefined;
} }
class Renderer implements ITreeRenderer<Element, void, HTMLElement> { class Renderer implements ITreeRenderer<Element, void, HTMLElement> {
...@@ -33,7 +42,7 @@ class Renderer implements ITreeRenderer<Element, void, HTMLElement> { ...@@ -33,7 +42,7 @@ class Renderer implements ITreeRenderer<Element, void, HTMLElement> {
return container; return container;
} }
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void { renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = element.element.id; templateData.textContent = element.element.id + (element.element.suffix || '');
} }
disposeTemplate(templateData: HTMLElement): void { disposeTemplate(templateData: HTMLElement): void {
// noop // noop
...@@ -65,7 +74,13 @@ class Model { ...@@ -65,7 +74,13 @@ class Model {
constructor(readonly root: Element) { } constructor(readonly root: Element) { }
get(id: string): Element { get(id: string): Element {
return find(this.root.children, id); const result = find(this.root, id);
if (!result) {
throw new Error('element not found');
}
return result;
} }
} }
...@@ -389,4 +404,36 @@ suite('AsyncDataTree', function () { ...@@ -389,4 +404,36 @@ suite('AsyncDataTree', function () {
assert(!hasClass(twistie, 'collapsible')); assert(!hasClass(twistie, 'collapsible'));
assert(!hasClass(twistie, 'collapsed')); assert(!hasClass(twistie, 'collapsed'));
}); });
test('issues #84569, #82629 - rerender', async () => {
const container = document.createElement('div');
const model = new Model({
id: 'root',
children: [{
id: 'a',
children: [{
id: 'b',
suffix: '1'
}]
}]
});
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], new DataSource(), { identityProvider: new IdentityProvider() });
tree.layout(200);
await tree.setInput(model.root);
await tree.expand(model.get('a'));
assert.deepEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a', 'b1']);
const a = model.get('a');
const b = model.get('b');
a.children?.splice(0, 1, { id: 'b', suffix: '2' });
await Promise.all([
tree.updateChildren(a, true, true),
tree.updateChildren(b, true, true)
]);
assert.deepEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a', 'b2']);
});
}); });
...@@ -614,16 +614,7 @@ export class CustomTreeView extends Disposable implements ITreeView { ...@@ -614,16 +614,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
const tree = this.tree; const tree = this.tree;
if (tree && this.visible) { if (tree && this.visible) {
this.refreshing = true; this.refreshing = true;
await Promise.all(elements.map(element => tree.updateChildren(element, true))); await Promise.all(elements.map(element => tree.updateChildren(element, true, true)));
elements.map(element => {
try {
tree.rerender(element);
} catch {
// noop
}
});
this.refreshing = false; this.refreshing = false;
this.updateContentAreas(); this.updateContentAreas();
if (this.focused) { if (this.focused) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册