【问题标题】:Is there a way to make install button work in VSCode extension Webview?有没有办法让安装按钮在 VSCode 扩展 Webview 中工作?
【发布时间】:2020-10-16 19:30:33
【问题描述】:

我们正在 gatsby.js 上制作一个 VSCode 扩展,并且我们有一个树形视图,点击时会显示一个 webview。在 web 视图中,我们有一个“安装按钮”,我们希望它通过向终端发送命令来运行“npm install pluginName”。

我们在一个名为“installPlugin”的类中有一个方法,它通过 npm API 解析以获取插件数据,例如 npm install plugin 命令。

对于 webview 内容,我们使用 panel.webview.html 添加 html 字符串。在按钮标签上,我们有一个 onclick 属性,它的值是 installPlugin 函数的调用。但是,该按钮在单击时不执行任何操作。相反,当单击树视图中的插件时(当 web 视图同时打开时),npm install 命令会运行。

某类中installPlugin方法的代码如下:

/* ---------- Logic handling the installation of Plugins and Themes --------- */

  async installPlugin(plugin?: any): Promise<void> {
    const activeTerminal = Utilities.getActiveTerminal();
    const gatsbyIsInitiated:
      | boolean
      | null = await Utilities.checkIfGatsbySiteInitiated();

    if (!gatsbyIsInitiated) {
      const input = await window.showErrorMessage(
        'Open up a new workspace containing only the site you are working on.',
        'Change Workspace',
        'Cancel'
      );
      if (input && input === 'Change Workspace') {
        commands.executeCommand('vscode.openFolder');
      }
      return;
    }
    // const rootPath = await Utilities.getRootPath();
    const { name, links } = plugin.command.arguments[0];
    if (plugin) {
      const installCmnd =
        (await PluginData.getNpmInstall(links.repository, links.homepage)) ||
        `npm install ${name}`;

      // if (rootPath) {
      //   activeTerminal.sendText(`cd && cd ${rootPath}`);
      //   activeTerminal.sendText(installCmnd);
      //   activeTerminal.show(true);
      // } else {
      // }
      activeTerminal.sendText(installCmnd);
      activeTerminal.show(true);
      // check for if "plugin" is a theme or actual plugin
      if (name.startsWith('gatsby-theme')) {
        window.showInformationMessage(
          'Refer to this theme\'s documentation regarding implementation. Simply click on the theme in the "Themes" section.',
          'OK'
        );
      } else {
        window.showInformationMessage(
          'Refer to this plugin\'s documentation regarding further configuration. Simply click on the plugin in the "Plugins" section.',
          'OK'
        );
      }
    }
  }

webview 面板的代码在这里:

export default class WebViews {
  static async openWebView(npmPackage: any) {
    // const { links, name, version, description } = npmPackage;
    const readMe = await PluginData.mdToHtml(links.repository, links.homepage);

    // turn npm package name from snake-case to standard capitalized title
    const title = name
      .replace(/-/g, ' ')
      .replace(/^\w?|\s\w?/g, (match: string) => match.toUpperCase());

    // createWebviewPanel takes in the type of the webview panel & Title of the panel & showOptions
    const panel = window.createWebviewPanel(
      'plugin',
      `Gatsby Plugin: ${title}`,
      ViewColumn.One
    );

    // create a header for each npm package and display README underneath header
    // currently #install-btn does not work
    panel.webview.html = `
    <style>
      .plugin-header {
        position: fixed;
        top: 0;
        background-color: var(--vscode-editor-background);
        width: 100vw;
      }

      #title-btn {
        display: flex;
        flex-direction: row;
        align-items: center;
        align-text: center;
      }

      #install-btn {
        height: 1.5rem;
        margin: 1rem;
      }

      body {
        position: absolute;
        top: 9rem;
      }
    </style>
    <div class="plugin-header">
      <div id="title-btn">
        <h1 id="title">${title}</h1>
        <button id="install-btn" onclick="${installPlugin(npmPackage)}">Install</button>
      </div>
      <p>Version: ${version}</p>
      <p>${description}</p>
      <hr class="solid">
    </div>
    ${readMe}
    `;

    // close the webview when not looking at it
    panel.onDidChangeViewState((e) => {
      if (!e.webviewPanel.active) {
        panel.dispose();
      }
    });
  }

总而言之,我们想知道是否有办法让 webview.panel.html 中的 onclick 属性引用类中的方法,即 installPlugin 方法。 webview 中的 html 似乎没有对 installPlugin 方法的任何引用。

【问题讨论】:

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


    【解决方案1】:

    您应该注意的最重要的事情是,您不能从扩展程序调用 webview 中的代码,反之亦然!一旦你内化,事情对你来说应该会变得更加明显。

    您所做的是发送消息,就像您对网络工作者所做的那样。您的按钮只能触发 webview 代码中的功能。这个函数应该向 vscode 发送一条消息。这反过来又会出现在您的扩展 webview 中。更多详情请参阅webview documentation,尤其是message passing paragraph

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多