在使用 Discourse 的 Ember API 插入 iframe 时遇到一些问题

该插件将一个 i-frame 插入到 Discourse 中,您可以在 此处 找到它。

我尽量将其保持在最新版本,因此破坏性更改是最近发生的。我们目前运行的是 3.3.0.beta1-dev。

在控制台中,我收到 3 条错误消息,如下所示:

docuss.js:225 Uncaught (in promise) ReferenceError: Ember is not defined
    at docuss.js:225:1

最有可能的是,这个 Ember 对象已在 Discourse 的最新版本中从 Discourse API 中移除,因此此错误是在 Discourse 升级影响到这些对象之后出现的。

这是我所做的所有修复:

更改 1

assets\javascripts\discourse\initializers\docuss.js.es6
第 232 行

旧:

const afterRender = res =>
  new Promise(resolve => {
    // @ts-ignore
    Ember.run.schedule('afterRender', null, () => resolve(res))

新:

import { schedule } from '@ember/runloop'

const afterRender = res =>
  new Promise(resolve => {
     schedule('afterRender', null, () => resolve(res))
  })

更改 2

assets\javascripts\discourse\lib\DcsIFrame.js.es6
第 858 行

旧:

  const afterRender = res =>
	new Promise(resolve => {
		Ember.run.schedule('afterRender', null, () => resolve(res))
	})

新:

	import { schedule } from '@ember/runloop'

	const afterRender = res =>
	  new Promise(resolve => {
		schedule('afterRender', null, () => resolve(res))
	  })

更改 3

assets\javascripts\discourse\lib\onDidTransition.js.es6
第 239 行

旧:

const afterRender = res =>
  new Promise(resolve => {
    Ember.run.schedule('afterRender', null, () => resolve(res))

新:

import { schedule } from '@ember/runloop'

const afterRender = res =>
  new Promise(resolve => {
      schedule('afterRender', null, () => resolve(res))

这清除了控制台中的所有错误消息,但产生了一系列新的错误消息:

 Discourse v3.3.0.beta1-dev — https://github.com/discourse/discourse/commits/4c7d58a883 — Ember v5.5.0
app.js:197 Uncaught ReferenceError: Ember is not defined
    at s.callback (docuss.js:210:1)
    at s.exports (loader.js:106:1)
    at requireModule (loader.js:27:1)
    at y (app.js:171:18)
    at w (app.js:194:19)
    at app.js:157:29
    at e.start (app.js:51:5)
    at HTMLDocument.<anonymous> (start-app.js:5:7)
    at discourse-boot.js:20:12
    at discourse-boot.js:1:1

如果插件已启用,您可以在此处找到一个实时平台,以防万一有帮助

这个问题是否有人遇到过 Ember API 对象更改的问题?非常感谢您能提供任何修复建议。

2 个赞

你好!

你漏掉了这个:

我认为你可以这样做。这仍然应该有效。

import { observes } from "discourse-common/utils/decorators";

@observes("model.tags")
tagsChanged() {

}

另外,作曲家控制器现在已移至服务

4 个赞

您是否查看了 GitHub 页面上的推荐替代方案?

我认为作者在这里很活跃。

1 个赞

感谢您的建议,@Heliosurge。不过,我们已经将旧的集成到我们的项目中很深了,所以在作者的许可下,我们接管了它的维护工作。

不过,我们目前的开源社区中,具备相关技能的开发人员有点少。

1 个赞

说得很有道理。

1 个赞

感谢您 @Arkshine。我的笔记本电脑在更换充电器烧坏了充电电路后就坏了,所以我直到昨天修复笔记本电脑后才能进行测试。

我把 import 语句放在了页面顶部,您的代码放在了下面,但在尝试添加它或类似的变体时似乎遇到了语法错误:

Visual Basic Studio 发现了这些错误:

// 使用 @observes 装饰器的新 tagsChanged 函数
@observes("model.tags")
tagsChanged() {
  // 检查它是否是气球标签

此行末尾的开括号:tagsChanged() {
有一个错误消息:
‘;’ 预期。ts(1005)

  1. 最后的花括号也有一个错误标记,消息为:
    预期 ‘}’。ts(1005)
    docuss.js.es6(219, 54):解析器在此处预期找到一个与 ‘{’ 标记匹配的 ‘}’。

这是第 219 行:
tagsChanged: Ember.observer('model.tags', function() {

当我尝试构建时,我的服务器显示这个:

  251 |     }, 0);
  252 |   }
> 253 | }.observes("model.tags"),
      |                          ^
        在 /tmp/broccoli-6523ExbXtskE5c0h/out-1067-funnel 中
        在 Babel (Babel: discourse-plugins)
  - name: Error
  - nodeAnnotation: Babel: discourse-plugins
  - nodeName: Babel
  - originalErrorMessage: /var/www/discourse/app/assets/javascripts/discourse/discourse/plugins/docuss/discourse/initializers/docuss.js: 意外的标记 (253:25)

我不知道为什么,但我从未能让这个修复生效,或者它的一些变体,这很奇怪,因为它在其他文件上工作得很好。我的注意力转移了一段时间,但它一直困扰着我。

现在回头看,我看不出是什么原因导致了这个问题。我已经将其恢复到原始状态。有人能看出需要在这里更改什么才能更新到新的 Ember API 吗?

这里有几点建议:

  • 站点设置已移至一个服务:

    const siteSettings = container.lookup('service:site-settings');
    if (!siteSettings.docuss_enabled) {
      return;
    }
    
  • location:discourse-locationlocation:history

  • afterRender().then(() => onAfterRender(container));
    afterRender 是一个装饰器,你将其放在组件类的方法上方;你不应该直接将其用作函数。
    我想你想要的是(似乎不需要),可能是:

    import { schedule } from '@ember/runloop';
    schedule("afterRender", () => onAfterRender(container))
    
  • 似乎有一大段代码不在 composeStateChanged 函数中。
    另外,你可以在这里使用路由服务:container.lookup('router:main').transitionTo(path);this.router.transitionTo(path);

  • 标题已现代化。在你的上下文中,home-logo 小部件中的自定义已弃用。更多信息请参见:https://meta.discourse.org/t/upcoming-header-changes-preparing-themes-and-plugins/296544。
    在你的情况下,你需要将 glimmer header mode 设置为 autoenabled。然后,你可以使用插件出口来替换内容:

    api.renderInOutlet("home-logo-contents", `
      <HomeLogoContents
        @logoSmallUrl={{container.dcsHeaderLogo._smallLogoUrl}}
        @logoUrl={{container.dcsHeaderLogo._logoUrl}}
        @minimized={{@outletArgs.minimized}}
        @mobileLogoUrl={{container.dcsHeaderLogo._mobileLogoUrl}}
        @showMobileLogo={{@outletArgs.showMobileLogo}}
        @title={{@outletArgs.title}}
      />
    `);
    

    注意:要使用 glimmer <template> 语法,请确保将文件扩展名重命名为 .gjs.
    你也可以使用这种方式:

     api.registerValueTransformer("home-logo-image-url", (transformer) => {
        let url = transformer.value;
        if (transformer.context.name === 'logo') {
          url = container.dcsHeaderLogo._logoUrl;
        } else if (transformer.context.name === 'logo_small') {
          url = container.dcsHeaderLogo._smallLogoUrl;
        } else if (transformer.context.name === 'logo_mobile') {
          url = container.dcsHeaderLogo._mobileLogoUrl;
        }
        return url;
      });
    

    要更改 URL:

    api.registerValueTransformer("home-logo-href", () => container.dcsHeaderLogo._href);
    

    注意:我认为在 setLogo 中重新渲染的代码在 glimmer 组件上将不起作用。

    注意(测试后):然而,这两种解决方案都将不起作用,因为标题在你可以从 JSON 中获取 logo 之前就已经渲染了。我没有现成的解决方案。我不确定是否有更好的方法:我会将 JSON 加载移到一个服务中并跟踪结果。然后,使用上面带有 glimmer 组件的插件出口。这样,基于一个跟踪变量,你可以自动触发组件的更新。

    这样,它在某种程度上是可行的。至少,没有更多的阻塞性错误了。:slightly_smiling_face:

    希望这有帮助。

3 个赞

非常有帮助,谢谢 :slight_smile:

1 个赞