实战CloudIDE插件开发-前后端方法互相调用

网友投稿 587 2022-05-30

通过实战CloudIDE插件开发-调试代码我们详细介绍了插件代码的调试方法,今天我们将用一个简单的功能示例继续深入到插件开发的细节。本次插件代码项目是通过CloudIDE的新建项目创建的Generic类型插件,就是具备前端独立页面和IDE后端运行时的插件,具体的创建步骤可以参考实战CloudIDE插件开发-快速上手,对于Backend类型的纯后端插件,可以使用CloudIDE已有的界面扩展点来实现前端功能,具体可以参考我们的API文档,由于Generic类型的插件本身包含后端能力,后续的教程中将不再对纯后端的插件进行过多介绍。

准备工作

已经创建并处于运行状态的CloudIDE实例,CloudIDE创建方法可以参考《5分钟创建并启动IDE实例》

本次插件示例代码:https://github.com/HuaweiIDE/cloudide-example-expose-api.git,可以通过文件->导入项目将代码导入到CloudIDE中。

新建终端并执行npm i安装依赖。

实战CloudIDE插件开发-前后端方法互相调用

后端调用前端

插件目录的详细介绍可以参考  《Directory Structures of Plugin Project》

在前端定义暴露给后端的的方法。

打开src/browser/frontend.ts文件,我们可以看到Frontend类继承自AbstractFrontend,默认需要实现init(), run(), stop()这三个方法,另外我们自定义了一个myApi(message: string)方法,如果我们想把这个运行在浏览器中的myApi方法暴露给后端去调用,我们只需要在函数上添加@expose('function_id')修饰器,注意多个expose修饰器中的function_id不要重复使用

import { LogLevel, WebviewOptions } from '@cloudide/core/lib/common/plugin-common'; import { PluginPage, AbstractFrontend } from '@cloudide/core/lib/browser/plugin-api'; import { exposable, expose } from '@cloudide/messaging'; /** * Adding your fronted api in this class * Using '@expose' to expose your function to backend */ @exposable class Frontend extends AbstractFrontend { /** * function call to the frontend will wait until init() to be resolved */ async init(): Promise { } /** * Entry of your plugin frontend * In this function your can call function exposed by backend */ run(): void { const myViewOptions: WebviewOptions = { viewType: 'my-webview', title: '%plugin.dynamicview.title%', targetArea: 'main', iconPath: 'resources/icons/plugin.svg', viewUrl: 'local:resources/page/dynamic-webview.ejs', preserveFocus: true, templateEngine: 'ejs' }; this.plugin.createDynamicWebview(myViewOptions, true); document.getElementById('call-print-on-dynamic-webview')?.addEventListener('click', evt => { //call function exposed on dynamic webview this.plugin.call('my-webview::myplugin.dynamic.page.print', 'param of function call from plugin main page'); }); document.getElementById('call-createNewFile-on-backend')?.addEventListener('click', evt => { //call function exposed on backend this.plugin.call('backend::createNewFile', 'untitled.txt').then((filePath) => { this.plugin.call('cloudide.window.showInformationMessage', `${filePath} created.`); }); }); } stop(): void { } /** * this function can be called from plugin backend as below: * @example * ``` * plugin.call('myplugin.page.myApi', 'this is a function call from backend').then(ret => { * console.log(ret); * }); * * ``` */ @expose('myplugin.page.myApi') public myApi(message: string) { const messageDom = document.createElement('div'); messageDom.append(document.createTextNode(`myApi called, param: ${message}`)); document.body.appendChild(messageDom); } } document.addEventListener('DOMContentLoaded', function() { PluginPage.create([Frontend]); });

在后端调用前端暴露的方法

打开src/node目录下的backend.ts,我们可以看到Backend类继承自AbstractBacend,默认需要实现init(), run(), stop()这三个方法,我们可以在run()方法中通过this.plugin.call()调用在前端定义的myAPI方法并获取到返回值。

import * as cloudide from '@cloudide/plugin'; import { exposable, expose } from '@cloudide/messaging'; import { LogLevel } from '@cloudide/core/lib/common/plugin-common'; import { AbstractBackend } from '@cloudide/core/lib/node/plugin-api'; /** * Add your backend api in this class * Using '@expose' to expose your function to frontend */ @exposable export class Backend extends AbstractBackend { /** * function call to the backend will wait until init() to be resolved */ async init(): Promise { } /** * Entry of your plugin backend * In this function you can call function exposed by frontend */ public async run(): Promise { const retValue = await this.plugin.call('myplugin.page.myApi', 'this is a function call from backend'); this.plugin.log(LogLevel.INFO, retValue); } public stop(): void { } /** * this function can be called from plugin frontend as below: * @example * ``` * plugin.call('your_backend_function_identifier', 'world').then(ret => { * console.log(ret); * }); * * ``` */ @expose('createNewFile') public async createNewFile(name: string) { const edit = new cloudide.WorkspaceEdit(); let absPath = name; if (cloudide.workspace.workspaceFolders) { const filePath = cloudide.Uri.file(`${cloudide.workspace.workspaceFolders[0].uri.fsPath}/${name}`); edit.createFile(filePath); cloudide.workspace.applyEdit(edit); absPath = filePath.path; } return absPath; } }

同样,我们可以在后端定义自己的方法并将方法暴露给前端调用,大家可以运行样例插件的代码测试下效果,也可以尝试自己添加想要的方法实现前后端的调用。插件调试运行可以参考《实战CloudIDE插件开发-调试代码》

CloudIDE TypeScript

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【AI实战营】resnet50算法调优
下一篇:Android’s PreferenceActivity for all API versions
相关文章