Я пишу расширение VS Code, которое реализует пользовательский viewsContainer.Он активируется в событии onView:
, указанном в пакете JSON.
Все это прекрасно работает, и мое представление извлекает данные из статического файла JSON и добавляет каждый узел в представление.
Мой JSON структурирован следующим образом:
{
"name": "root",
"children": {
"Child1": [
{ "id": "childId1", "name": "childName1" },
{ "id": "childId2", "name": "childId2" }
],
"Child2": [
{ "id": "childId1", "name": "childName1" },
{ "id": "childId2", "name": "childId2" }
],
"Child3": [
{ "id": "childId1", "name": "childName1" },
{ "id": "childId2", "name": "childId2" }
],
"Child4": [
{ "id": "childId1", "name": "childName1" },
{ "id": "childId2", "name": "childId2" }
]
}
}
, а мой класс, который зарегистрирован как провайдер дерева в extension.ts
, имеет вид:
import * as vscode from "vscode";
import * as validateMenuItems from "./validateMenuItems.json";
export class ValidateMenuProvider
implements vscode.TreeDataProvider<ValidateMenu> {
private _onDidChangeTreeData: vscode.EventEmitter<
ValidateMenu | undefined
> = new vscode.EventEmitter<ValidateMenu | undefined>();
readonly onDidChangeTreeData: vscode.Event<ValidateMenu | undefined> = this
._onDidChangeTreeData.event;
constructor() {}
refresh(): void {
this._onDidChangeTreeData.fire();
}
getTreeItem(element: ValidateMenu): vscode.TreeItem {
if(element) {
console.log(`element: ${element}`);
return element;
}
return element;
}
getChildren(element?: ValidateMenu): Thenable<ValidateMenu[]> {
if (element) {
return Promise.resolve([]);
} else {
return Promise.resolve(this.getValidateMenu());
}
}
private getValidateMenu(): ValidateMenu[] {
const toMenu = (
menuTitle: string,
collapsibleState: vscode.TreeItemCollapsibleState
): ValidateMenu => {
return new ValidateMenu(menuTitle, collapsibleState);
};
let menuItems: any = [];
let menuHeadings: any = validateMenuItems.children;
let j: number = 0;
for (var i in menuHeadings) {
// send the parent as a menu item
if (menuHeadings[i] !== null && typeof menuHeadings[i] === "object") {
let firstChildLabel: string = Object.keys(validateMenuItems.children)[
j
];
let parentMenuItem = toMenu(
firstChildLabel,
vscode.TreeItemCollapsibleState.Collapsed
);
menuItems.push(parentMenuItem);
// send each child object to the view
for (var k = 0; k < menuHeadings[i].length; k++) {
if (
menuHeadings[i][k] !== null &&
typeof menuHeadings[i][k] === "object"
) {
let secondChildLabel: string = menuHeadings[i][k].name;
let childMenuItem = toMenu(
secondChildLabel,
vscode.TreeItemCollapsibleState.None
);
menuItems.push(childMenuItem);
} else {
return [];
}
}
} else {
return [];
}
j++;
}
return menuItems;
}
}
export class ValidateMenu extends vscode.TreeItem {
constructor(
public readonly label: string,
public readonly collapsibleState: vscode.TreeItemCollapsibleState,
public readonly command?: vscode.Command
) {
super(label, collapsibleState);
}
}
То, что это делает, помещает каждый элемент вJSON в представлении, первый набор объектов в root.children
как свернутые элементы и их соответствующие дочерние элементы как неразборчивые / сворачиваемые.
Однако для каждого из расширяемых элементов, если я щелкну, чтобы развернутьТаким образом, вся остальная схема JSON повторяется под ней.
После перехода и просмотра кадров стека вызовов оказывается, что запрашиваемый метод getChildren()
сначала вызывается при регистрации провайдера, и приКаждое событие расширения.
Мой вопрос - поскольку getChildren()
требует <Thenable>
, где я ошибаюсь с моей реализацией с getValidateMenu()
, которая позволит избежать дублированияg схему на свернутых объектах и на самом деле сгруппировать дочерние объекты в свернутый элемент?
Нужно ли непосредственным элементам root.children
иметь команду, которая вызывает какой-то метод onclick
, которыйполучает this
и раскрывает своих детей?
Любые указатели от тех, кто более знаком, высоко ценится.