Skip to content

Conversation

@TCOTC
Copy link
Contributor

@TCOTC TCOTC commented Oct 29, 2025

给插件添加 onDataChanged 方法,用来替代同步之后插件先 onunload 再 onload,解决我在 #15444 (comment) 遇到的问题

基于前一个 PR 修改,需要先合并:#16243


需要测试:

  • 存在 onDataChanged 方法
  • 不存在 onDataChanged 方法

  • 文件删除
  • 文件夹删除
  • 文件新增
  • 文件夹新增
  • 文件内容更新

@TCOTC TCOTC force-pushed the feat/onDataChanged branch from c2ba4dc to f387e77 Compare November 2, 2025 10:06
@TCOTC TCOTC marked this pull request as ready for review November 2, 2025 10:06
@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 2, 2025

可以 review 了

@88250 88250 requested a review from Vanessa219 November 4, 2025 01:42
@88250 88250 added this to the 3.4.0 milestone Nov 6, 2025

export const reloadPlugin = async (app: App, data: { upsertPlugins: string[], removePlugins: string[] }) => {
data.removePlugins.forEach((item) => {
export const reloadPlugin = async (app: App, data: { upsertCodePlugins?: string[], upsertDataPlugins?: string[], removePlugins?: string[] } = {}) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upsertCodePlugins 这个为什么要加 Code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

插件代码有变化就需要重新加载插件


export const reloadPlugin = async (app: App, data: { upsertPlugins: string[], removePlugins: string[] }) => {
data.removePlugins.forEach((item) => {
export const reloadPlugin = async (app: App, data: { upsertCodePlugins?: string[], upsertDataPlugins?: string[], removePlugins?: string[] } = {}) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upsertDataPlugins 会有对应的 removeData 么?这个参数是 Data,应该不用加 plugins 后缀了。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

插件删除配置文件也算在 upsertDataPlugins 内

}
});
}
reloadPlugins.push(pluginName);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要去重

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 7, 2025

  • upsertCodePlugins:插件代码变化
  • upsertDataPlugins:插件存储文件变化
  • removePlugins:插件被卸载

@Vanessa219
Copy link
Member

看了你的回复,发现这并不是处理 data change 的。抱歉,没注意看前面的 #15444 (comment) 。如果要处理禁用状态下卸载插件的话,可以加一个阶段为 uninstalled,即卸载成功后的回调。你看这样可以么?

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 7, 2025

前面那个 issue 之所以需要在没有启用插件的情况下卸载插件,是因为把 onunload 方法用来处理插件配置同步了,现在增加一个新的 onDataChanged 方法就可以使用正常的 onunload 方法在前端卸载插件了。

我感觉没有什么办法能在不启用插件的情况下执行 uninstall。

@Vanessa219
Copy link
Member

Vanessa219 commented Nov 7, 2025

这个是卸载的问题,和 data change 没有关系。这样开发者可能无法理解,我也不太理解。一开始我就误解为插接数据变化的同步。

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 7, 2025

确实是插件存储的数据的变化,就是 this.data

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 7, 2025

正常情况下 onunload() 应该移除插件在前端添加的所有组件,但之前的逻辑是存储数据变更会先执行 onunload() 再执行 onload(),同步一下插件配置就会把组件全部移除的话交互太奇怪了,所以我就把完整的 onunload() 逻辑移到 uninstall() 里去了,然后就会导致一个问题,如果用户先禁用插件再卸载插件的话就只会执行 onunload(),一部分组件还留在界面上。

增加一个单独的 onDataChanged() 方法的话,我就可以把 uninstall() 里的逻辑移回 onunload(),把 onDataChanged() 用来处理配置同步,onunload() 用来完整移除组件,uninstall() 只额外执行一步 removeData(),这样就基本没有在禁用插件时卸载插件执行 uninstall() 的需求了。

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 7, 2025

实际上这个 PR 单纯就是用来处理数据同步的,不看之前那个 issue 也完全没有影响

@Vanessa219
Copy link
Member

Vanessa219 commented Nov 8, 2025

如果不看前一个 issue,把这个做为数据更改的话,它又和 onunload,uninstall 这些生命周期混杂在一起。还是没搞懂这个的用途和价值。

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 8, 2025

目前数据同步之后插件会执行 onunload() 和 onload(),增加一个 onDataChanged() 就不需要执行 onunload() 和 onload() 了

@Vanessa219
Copy link
Member

但是 changeDate 不应该和 onunload() onload() 搅合在一起

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 8, 2025

我没理解你的意思

@Vanessa219
Copy link
Member

onDataChanged 应该只是在数据有改动时回调他,不应该去 onunload 和 onload

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 9, 2025

那我的代码有什么问题呢?

@Vanessa219
Copy link
Member

如果要解决 #15444 (comment) 这个问题的话,不应该叫 dataChange;如果要添加 dataChange 的话,不应该和生命周期混在一起。

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 9, 2025

这个 PR 不能实现“在禁用状态卸载插件”,而是能让我的插件不再需要“在禁用状态卸载插件”这个需求

@88250 88250 removed this from the 3.4.0 milestone Nov 13, 2025
@Vanessa219 Vanessa219 merged commit 9bfe00c into siyuan-note:dev Nov 25, 2025
3 checks passed
@Vanessa219 Vanessa219 added this to the 3.4.2 milestone Nov 25, 2025
@TCOTC TCOTC deleted the feat/onDataChanged branch November 25, 2025 08:53
Vanessa219 added a commit that referenced this pull request Nov 26, 2025
@Vanessa219 Vanessa219 self-assigned this Nov 26, 2025
@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 26, 2025

@Vanessa219 upsertDataPlugins 的插件如果没有实现 onDataChanged() 方法,或者执行 onDataChanged() 方法出现异常了,就需要关闭再打开

PixPin_2025-11-26_10-34-42

@Vanessa219
Copy link
Member

为什么?

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 26, 2025

  1. 关闭再打开是旧逻辑,不能破坏。onDataChanged() 是渐进增强,有实现这个方法的插件才不需要关闭再打开
  2. 出现异常的话说明这个方法不能正常执行,就需要回退到旧逻辑

@Vanessa219
Copy link
Member

onDataChanged 这个应该只针对数据修改,不应该去进行卸载和加载插件。没有实现的话不处理即可。

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 26, 2025

不能破坏已有的逻辑,没办法要求所有插件都立即加上 onDataChanged 方法。

@Vanessa219
Copy link
Member

不加的话就不需要处理。这个是新加的功能,不会破坏已有的。

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 26, 2025

已有的逻辑是关闭再打开。你可以试试修改插件配置之后同步,另一个客户端上的插件会关闭再打开

@Vanessa219
Copy link
Member

说的是新加的 onDataChanged,这个和已有的不存在关系。

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 26, 2025

已有的逻辑是插件配置同步之后会把插件关闭再打开:

video.webm

最新的代码去掉了这个逻辑,破坏了插件配置同步的功能:

video.webm

@Vanessa219
Copy link
Member

那需要发个通知让插件去更新 @88250

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 26, 2025

只要把 1d19028 改回来就正常了

Vanessa219 added a commit that referenced this pull request Nov 26, 2025
@Vanessa219
Copy link
Member

那还是兼容了一下这个历史问题吧。

@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 26, 2025

版本号错了:

PixPin_2025-11-26_20-09-12

Vanessa219 added a commit that referenced this pull request Nov 26, 2025
Vanessa219 added a commit to siyuan-note/petal that referenced this pull request Nov 27, 2025
@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 30, 2025

我注意到目前的实现还有一点缺陷,等我改完 PR

@88250
Copy link
Member

88250 commented Nov 30, 2025

好的

Vanessa219 pushed a commit to siyuan-note/plugin-sample that referenced this pull request Nov 30, 2025
TCOTC added a commit to TCOTC/siyuan that referenced this pull request Nov 30, 2025
fix siyuan-note#16244

重构、修复插件重启逻辑

重构

比如插件在 onload() 中插入了图标,uninstall 会把图标删除,afterLoadPlugin 又不能执行 onload() 把图标加回来

使用 getElementById

先加载插件样式

避免插入重复的样式

改进插件样式插入位置
@TCOTC
Copy link
Contributor Author

TCOTC commented Nov 30, 2025

#16472

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants