Visual studio code 有没有办法让安装按钮在VSCode扩展Webview中工作?

Visual studio code 有没有办法让安装按钮在VSCode扩展Webview中工作?,visual-studio-code,webview,vscode-extensions,Visual Studio Code,Webview,Vscode Extensions,我们在gatsby.js上做了一个VSCode扩展,我们有一个树视图,当点击时显示一个webview。在webview中,我们有一个“安装按钮”,我们希望它通过向终端发送命令来运行“npm install pluginName” 我们在一个名为“installPlugin”的类中有一个方法,它通过NPMAPI解析以获得插件数据,例如npm install plugin命令 对于webview内容,我们使用panel.webview.html添加html字符串。在按钮标签上,我们有一个onclic

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

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

对于webview内容,我们使用
panel.webview.html
添加html字符串。在按钮标签上,我们有一个onclick属性,其值是installPlugin函数的调用。但是,单击按钮时,它不会执行任何操作。相反,当单击树视图中的插件时(当webview同时打开时),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'
        );
      }
    }
  }
/*------------处理插件和主题安装的逻辑------*/
异步安装插件(插件?:任意):承诺{
const activeTerminal=Utilities.getActiveTerminal();
康斯特·盖茨比:
|布尔值
|null=等待实用程序。checkIfGatsbySiteInitiated();
如果(!gatsby启动){
常量输入=等待窗口。消息(
“打开一个新的工作区,其中只包含您正在使用的站点。”,
“更改工作区”,
“取消”
);
如果(输入和输入==='更改工作区'){
commands.executeCommand('vscode.openFolder');
}
返回;
}
//const rootPath=wait Utilities.getRootPath();
const{name,links}=plugin.command.arguments[0];
如果(插件){
常量安装CMND=
(等待PluginData.getNpmInstall(links.repository,links.homepage))||
`npm安装${name}`;
//if(根路径){
//sendText(`cd&&cd${rootPath}`);
//activeTerminal.sendText(installCmnd);
//activeTerminal.show(true);
//}其他{
// }
activeTerminal.sendText(installCmnd);
activeTerminal.show(true);
//检查“插件”是主题还是实际插件
if(name.startsWith('gatsby-theme')){
window.showInformationMessage(
'请参阅此主题的有关实现的文档。只需单击“主题”部分中的主题即可。',
“好的”
);
}否则{
window.showInformationMessage(
'有关进一步配置,请参阅此插件的文档。只需单击“插件”部分中的插件即可。',
“好的”
);
}
}
}
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();
      }
    });
  }
导出默认类Web视图{
静态异步openWebView(npmPackage:any){
//const{links,name,version,description}=npmPackage;
const readMe=wait PluginData.mdToHtml(links.repository,links.homepage);
//将npm包名称从snake case改为标准大写标题
const title=名称
.替换(/-/g'')
.replace(/^\w?|\s\w?/g,(match:string)=>match.toUpperCase());
//createWebviewPanel采用webview面板的类型以及面板和showOptions的标题
const panel=window.createWebviewPanel(
“插件”,
`盖茨比插件:${title}`,
ViewColumn.1
);
//为每个npm包创建一个标题,并在标题下显示自述
//目前#安装btn不起作用
panel.webview.html=`
.插件头{
位置:固定;
排名:0;
背景颜色:var(--vscode编辑器背景);
宽度:100vw;
}
#标题btn{
显示器:flex;
弯曲方向:行;
对齐项目:居中;
对齐文本:居中;
}
#安装btn{
高度:1.5雷姆;
保证金:1rem;
}
身体{
位置:绝对位置;
顶部:9rem;
}
${title}
安装
版本:${Version}

${description}


${readMe} `; //不查看Web视图时关闭它 panel.onDidChangeViewState((e)=>{ 如果(!e.webviewPanel.active){ panel.dispose(); } }); }

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

您应该知道的最重要的一点是,您不能ot从扩展调用webview中的代码,反之亦然!一旦您内部化,事情应该变得更加明显

相反,您要做的是发送消息,就像您对web workers所做的那样。您的按钮只能触发webview代码中的一个函数。此函数应向vscode发送消息。这反过来又会在扩展webview中结束。有关更多详细信息,请参阅,尤其是