面板与扩展的通信

一些实用工具或者是简单的功能可以直接写在面板上,但是面板不是可靠的数据存储位置,窗口随时可能被关闭,面板也会被关闭。

最常见的例子就是某个面板被拖拽停靠到主窗口里。这时候面板会先关闭,然后在主窗口内重新打开,而面板上使用的内存里的数据如果不进行存储和备份,则会随着重启而丢失。

这时候就需要与扩展主体进行一定程度的数据交互。

在看这章节前,需要对 消息系统 有一定程度的了解。

定义扩展上和面板的方法

首先我们定义一份 package.json:

  1. {
  2. "name": "hello-world",
  3. "main": "./browser.js",
  4. "panels": {
  5. "default": {
  6. "title": "hw",
  7. "main": "./panel.js"
  8. }
  9. },
  10. "contributions": {
  11. "messages": {
  12. "upload": {
  13. "methods": ["saveData"]
  14. },
  15. "query": {
  16. "methods": ["queryData"]
  17. }
  18. }
  19. }
  20. }

然后定义扩展的 main 文件 browser.js

  1. exports.methods = {
  2. saveData(path, data) {
  3. // 收到数据后缓存起来
  4. this.cache[path] = data;
  5. },
  6. queryData(path) {
  7. const result = this.cache[path];
  8. delete this.cache[path];
  9. return result;
  10. },
  11. };
  12. exports.load = function() {};
  13. exports.unload = function() {};

然后定义面板的 main 文件:

  1. const packageJSON = require('./package.json');
  2. exports.ready = async () => {
  3. const tab = await Editor.Message.request(packageJSON.name, 'query', 'tab');
  4. const subTab = await Editor.Message.request(packageJSON.name, 'query', 'subTab');
  5. // 打印查询到的数据
  6. console.log(tab, subTab):
  7. // TODO 使用这两个数据初始化
  8. };
  9. exports.close() {
  10. // 收到数据后上传到扩展进程
  11. Editor.Message.send(packageJSON.name, 'upload', 'tab', 1);
  12. Editor.Message.send(packageJSON.name, 'upload', 'subTab', 0);
  13. };

发送消息

当定义好扩展和扩展里的面板后,就可以尝试触发这些消息。

按下 ctrl(cmd) + shift + i 打开控制台。在控制台打开面板:

  1. // default 可以省略,如果面板名字是非 default,则需要填写 'hello-world.xxx'
  2. Editor.Panel.open('hello-world');

打开面板后,控制台会打印出一句:

  1. undefined, undefined

这是因为数据还没有提交。关闭这个面板,然后再次打开,这时候控制台打印出了数据:

  1. 1, 0

这是因为面板在关闭的时候,发送了两条消息:

  1. Editor.Message.send(packageJSON.name, 'upload', 'tab', 1);
  2. Editor.Message.send(packageJSON.name, 'upload', 'subTab', 0);

通过这两条消息,Message 系统首先根据 messages 里的 upload 定义 "methods": ["saveData"],将数据保存到扩展进程里。当再次打开面板时,通过以下代码查询到刚刚保存的数据,并初始化界面、打印到控制台:

  1. const tab = await Editor.Message.send(packageJSON.name, 'query', 'tab');
  2. const subTab = await Editor.Message.send(packageJSON.name, 'query', 'subTab');

至此,我们完成了一次面板与扩展进程的交互。