重复的TreeView架构是VS代码扩展

时间:2019-03-29 13:30:04

标签: typescript visual-studio-code vscode-extensions

我正在编写一个实现自定义viewsContainer的VS Code扩展。在包JSON中指定的onView:事件中将其激活。

这一切都很好,我的视图从静态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中注册为treeviewprovider的班级是:

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()的实现中出错了,这将避免在折叠的对象上复制架构,而实际上将其分组折叠项中的子对象?

直接root.children项是否需要有一个调用某种onclick方法的命令,该命令可以获取this并显示其子项?

任何更熟悉的人的指针都将受到赞赏。

2 个答案:

答案 0 :(得分:1)

您没有正确实现getChildren()。记录如下:

  

获取Right或子级的子级(如果未传递任何元素)。

您的实现似乎要做的是“在没有传递Right (+3) <*> Right 3 => Right 6 时返回所有树项目的平面列表,否则返回一个空列表”。

您实际上需要返回请求的element的子代(并且仅返回直接子代,而不是立即为根元素返回整个树)。

官方Tree View Sample可能值得一试。

答案 1 :(得分:1)

即使我为此苦苦挣扎了很长时间,还是在另一个问题中发现了OP共享的github存储库。我认为在这里值得一提,以使其他人受益。

https://github.com/trebleCode/dxdevcheck/blob/master/src/validateMenu.ts

对我来说,关键是将children字段添加到我的TreeItem子类中,如@ Gama11在评论中所述。