重复的 TreeView Schema 是 VS Code 扩展 [英] Duplicate TreeView Schema is VS Code Extension

查看:18
本文介绍了重复的 TreeView Schema 是 VS Code 扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个实现自定义视图容器的 VS Code 扩展.它在包 JSON 中指定的 onView: 事件中激活.

这一切都很好,我的视图从静态 JSON 文件中提取数据并将每个节点添加到视图中.

我的 JSON 结构如下:

<代码>{"name": "root",孩子们": {孩子1":[{ "id": "childId1", "name": "childName1" },{ "id": "childId2", "name": "childId2" }],孩子2":[{ "id": "childId1", "name": "childName1" },{ "id": "childId2", "name": "childId2" }],孩子3":[{ "id": "childId1", "name": "childName1" },{ "id": "childId2", "name": "childId2" }],孩子4":[{ "id": "childId1", "name": "childName1" },{ "id": "childId2", "name": "childId2" }]}}

并且我在 extension.ts 中注册为 treeviewprovider 的类是:

import * as vscode from "vscode";import * as validateMenuItems from "./validateMenuItems.json";导出类 ValidateMenuProvider实现 vscode.TreeDataProvider{私有_onDidChangeTreeData:vscode.EventEmitter<验证菜单 |不明确的>= new vscode.EventEmitter();只读 onDidChangeTreeData: vscode.Event= 这个._onDidChangeTreeData.event;构造函数(){}刷新():无效{this._onDidChangeTreeData.fire();}getTreeItem(element: ValidateMenu): vscode.TreeItem {如果(元素){console.log(`元素:${元素}`);返回元素;}返回元素;}getChildren(element?: ValidateMenu): Thenable{如果(元素){返回 Promise.resolve([]);} 别的 {返回 Promise.resolve(this.getValidateMenu());}}私有 getValidateMenu(): ValidateMenu[] {const toMenu = (菜单标题:字符串,collapsibleState: vscode.TreeItemCollapsibleState): 验证菜单 =>{返回新的 ValidateMenu(menuTitle, collapsibleState);};让 menuItems: any = [];让 menuHeadings: any = validateMenuItems.children;让 j: 数字 = 0;for (var i in menuHeadings) {//将父项作为菜单项发送if (menuHeadings[i] !== null && typeof menuHeadings[i] === "object") {让 firstChildLabel: string = Object.keys(validateMenuItems.children)[j];让 parentMenuItem = toMenu(第一个子标签,vscode.TreeItemCollapsibleState.Collapsed);menuItems.push(parentMenuItem);//将每个子对象发送到视图for (var k = 0; k 

这样做是将 JSON 中的每个项目放入视图中,将 root.children 下的第一组对象作为折叠项目,并将它们各自的子项作为不可展开/可折叠的.

但是,对于每个可展开的项目,如果我点击展开它,整个 JSON 架构的其余部分都会在其下方重复.

从单步执行和观察调用堆栈帧来看,似乎需要的 getChildren() 方法最初是在注册提供者和每个展开事件时首先调用的.

我的问题是 - 由于 getChildren() 需要 <Thenable>,所以我使用 getValidateMenu() 这将避免在折叠对象上复制架构,并且实际上将它的子对象分组在折叠项目中?

直接root.children 项是否需要有一个命令来调用某种onclick 类型的方法,该方法获取this 和揭示它的孩子?

非常感谢那些更熟悉的人的任何指示.

解决方案

您没有实施 getChildren() 正确.记录如下:

<块引用>

获取 element 的子元素,如果没有元素传递,则获取根元素.

您的实现似乎做的是当没有 element 被传递时,返回一个 所有 树项的平面列表,否则返回一个空列表".

您需要实际返回请求的 element 的子元素(并且仅返回直接子元素,而不是一次为根元素返回整个树).

官方树视图示例可能值得一试.

I'm writing a VS Code extension that implements a custom viewsContainer. It is activated in an onView: event specified in the package JSON.

This all works great, and my view pulls in data from a static JSON file and does add each node to the view.

My JSON is strucutured like this:

{
  "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" }
    ]
  }
}

and my class that is registered as a treeviewprovider in extension.ts is:

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);
  }
}

What this does is put every item in the JSON into the view, the first set of object under root.children as collapsed items, and their respective children as non-expandable/collapsible.

However, for each of the expandable items, if I click to expand it, the entire rest of the JSON schema is repeated underneath it.

From stepping through and watching the call stack frames it appears that the requried getChildren() method is first initially called when the provider is registered, and at each expand event.

My question is - since getChildren() requires a <Thenable>, where am I going wrong with my implementation with getValidateMenu() that will avoid duplicating the schema on the collapsed objects, and actually group it's child objects within the collapsed item?

Do the immediate root.children items need to have a command that calls some kind of onclick sort of method, that gets this and reveals its children?

Any pointers from those more familiar greatly appreciated.

解决方案

You're not implementing getChildren() correctly. It's documented like this:

Get the children of element or root if no element is passed.

What your implementation seems to do instead is "return a flat list of all tree items when no element is passed, and an empty list otherwise".

You need to actually return the children of the requested element (and only the immediate children, instead of returning the whole tree at once for the root element).

The official Tree View Sample might be worth checking out.

这篇关于重复的 TreeView Schema 是 VS Code 扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆