分享一些简单的弹出窗口 modals 方便任何其他插件复用作 API

上传啦,仓库地址 obsidian-ample-modal-example
我没有 Node.js 所以在 main.js 里 require 的是绝对路径,大家记得改成自己的路径哦!


借用 QuickAdd 的 this 实现多栏提交窗口 继续讨论:

最近又学了点,不再借用其他插件的 this,写了几个常用的弹出窗口汇总到一个“modals.js”里,可以便捷引入到任何插件作 API。没什么技术含量,单纯减轻重复劳动。

目前有这些 modals:

但查看其他社区插件,如 QuickAdd、Modal forms,我发现作者们使用 .svelte 文件来写 modals。想咨询大家是不是更推荐这么写,不太用得上我这种?如果是这样,我还是自己留着耍得了 :rofl:

一些额外的问题:

  1. Svelte 是不是更加方便,或者比较好迁移到别的软件,或者这是计算机行业的标准?
  2. 我知道 TypeScript 需要安装环境,所以我就没有安装。Svelte 也是这样,没有任何办法能够直接在 JS 中使用吗(我搜索到似乎要安装 Node.js 之类的才能用)?

svelte 是一个框架,负责用js生成dom。同类的框架还有 react、vue 这些。
用这些框架是因为写起来更直观,处理界面变化更简单一些。

但是用这些框架需要建立一个npm项目,需要一个打包器把框架和代码打包起来,会比较复杂一些。

如果功能简单,直接用 js 也挺好的。

你这种写法确实很好,免去安装npm的麻烦,不知道在哪学来的?你这种用法是直接放到插件的main.js中使用吗还是放到quickadd中?在插件外能用吗?

我在插件的main.js中测试成功,但quickadd中不行,可能我方法不对。

关于额外的问题

  1. Svelte,vue,react等就是一种编写ui界面的框架,框架就是工具,不存在标准不标准的,不过,现在大家写正式项目基本都会使用框架的,中小公司vue,大型公司react,Svelte目前国内还不流行。关于迁移到别的软件,当然不用框架迁移起来最方便了。所以使用框架并不是为了更好迁移,是为了高效编程。因为原生js需要手动处理数据和dom之间的交互问题,会非常麻烦,而上面这些框架解决了这些问题。让开发更专注于数据本身或者是功能本身。

  2. Svelte,vue,react这些都可以通过不安装nodejs,使用cdn或直接浏览器引用的方式实现,vue,react官方有说明,Svelte没研究过,好像稍微麻烦。另外,TypeScript本身并不一定需要nodejs环境,但为了让浏览器等更好的支持必须编译为js5,这些编译打包的工具是用nodejs开发的,所以编译ts自然需要nodejs环境了。如果你用vscode,有插件支持把ts编译为js5,当然,ts一般都是配合正式项目使用的,基本上要与其他框架配合使用,如果仅仅做ts学习演示,用插件编译足矣。但这种小众方式资料往往是比较少的(包括上面说的非node方式使用框架)。

当然,小项目我选择原生js手写感觉更方便。 :grinning: 或者用jquery ui, layui, amazeui等,当然也有一些小型的针对特定组件的ui,比如弹窗等。

@the_tree @wilson 感谢二位详细回复!能用得上就行,我已经把代码上传至 #1 链接的仓库中了。

下面回复一些补充信息:

是在哪学的?

起因是原先使用 const 定义函数,然后在 JS 档末尾用 module.exports 导出,但这样每次要抄两遍函数名字很麻烦,所以学了一点 JS class,是通用的。

为什么好像插件外不能直接使用?

这可能是因为目前 Obsidian 只在插件文件夹第一层名为 main.js 的 JS 文件提供 obsidian、codemirror 6 等,所以其他地方可能找不到模块。

QuickAdd 能用吗?有办法在插件外用吗?

这是使用 QuickAdd Capture console.log(this) 在开发控制台的输出截图:

Pasted image 20240528134832 Pasted image 20240528134927

易得,这个 this 在 QuickAdd Marco 里对应的就是下图红框位置:

Pasted image 20240528134616

正如图片所示,QuickAdd 的 this 里是有 appobsidian 的,所以绝对是可以使用的,但由于获取的位置不同,不能直接复制本话题中的代码,而要稍微捣腾一下。#1 引入文章分享有旧版的 rgx_form_modal,是完整可运行的 QuickAdd Macro 代码,可以先粘贴来试一试。

同理,对于 Dataview,dv 就是 this。Dataview 获取 obsidian 又另有不同,可以直接在代码块内获取到,但却不在 this 中:

console.log(dv)
console.log(this)
console.log(obsidian)

那么,既然我们能获取其他插件的 this,我们肯定也有办法获取自己插件的 this。让我们试着在 Dataview 书写如下代码:

const api = app.plugins.plugins['ample-modal'].mySimpleApi
// 或者规范地写作 dv.app.plugins.plugins['ample-modal'].mySimpleApi
console.log(api)
// 试着用一下:
const r = await api.inputPrompt('请输入'); console.log(r)

现在,控制台中输出的结果就是插件 ID 为 ample-modalthis.mySimpleApi 了。

只要我们保证 ample-modal 插件在我们使用这段代码前是加载好的,我们就可以在 Obsidian 内任何能够执行代码的地方使用自己的 API 了。

一般对于重 UI 的项目,大部分都会采用 react/vue/svelte 这样的响应式 UI 框架,框架不仅提供数据响应式,而且是组件式开发,同时再基于 npm 进行依赖管理,这一整套就是现在前端开发最流行的方式。当然也包括ts

谢谢,学习了,目前发现quickadd, dataviewjs, runjs, Templater中都能用obsidian模块,相应的它导出的成员,比如Modal,Plugin等自然也能用了。

控制台等可以使用 obsidian-fix-require-modules 这个插件,只是没研究明白,如果不使用插件,也不借用quickadd,dataview等,在插件外,怎么自己实现加载obsidian模块,看了obsidian-fix-require-modules插件源码, 一脸懵逼,对模块加载不太了解。

根据你的方法,我简化了两个在插件外调用的方法(以quickadd为例)

// 插件外使用modal模块
module.exports = ({ quickAddApi, obsidian })=> {
  const modal = (obsidian) => class extends obsidian.Modal {
    constructor(app) { super(app); }
    onOpen() {
      alert('i am modal');
    }
    onClose() {  }
  }

  const pop = modal(obsidian)
  new pop(app).open()
}


// 插件外使用plugin模块
 module.exports = ({ quickAddApi, obsidian })=> {
    const plugin = (obsidian) => class extends  obsidian.Plugin {
      constructor(app, manifest) {
        super(app, manifest)
      }
      onload() {
        alert('i am plugin');
      }
      onunload() {}
   }
  const myPlugin = plugin(obsidian)
  new myPlugin(app).onload()
 }

对了,提醒下,发现你封装的插件,main.js里路径写死了

this.mySimpleApi = new (require('D:/Global Edu/.obsidian/plugins/ample-modal/src/modals.js'))(app, ob)

我改成了

const basePath = app.vault.adapter.basePath;
const pluginDir = basePath + '/' + app.plugins.manifests['ample-modal'].dir;
this.mySimpleApi = new (require(pluginDir+'/src/modals.js'))(app, ob)

@champ 感谢回复,学习了!

@wilson 感谢修改代码!确实如果要分享的话应该用 app.vault.adapter.basePath 这样写会更好。因为我在其他地方也有用 require,我发现如果用凑路径的方式,高亮会错误,比如原本函数应该高亮为黄色,如果凑路径的话就会高亮为蓝色,就统一没有用了。

另外考虑到大家可能会大多数人都会有 Node.js,如果有的话就不用写绝对路径,可以写相对路径,就没有这个问题了。此外,JS 文件本身是可以多处引用的,也考虑到可能有人只是作为一个引入文件,这样的话放在电脑哪里都有可能,直接填路径可能会宽松一些。

哈哈,可能是代码编辑器高亮程序匹配问题,应该问题不大。

上次我在官方插件审核区看到官方不建议在代码里写.obsidian路径,因为.obsidian只是默认值,在配置里可能被修改。

我一般用 app.vault.configDir 代替。

原来配置文件夹也可以更改,之前没有注意到,感谢提醒!绝对路径是这样的,有啥更改我就指望 VSCode 的批量替换了。一般人有安装环境的话,还是用相对路径好。

哈哈,是的。我想官方设这个可更改的目的可能是为了快速切换不同的环境,比如我一个笔记仓库可以切换不同的配置,具体就不知道了。我以前也不知道,还是在官方插件审核那里看官方的批复,犯这个错误的应该不少,去看了几次都发现有此类问题。