如何在 VanillaJS 中访问跟踪的变量?

我有这段代码:

let iFrame = document.getElementById('oc-editor');
iFrame.addEventListener('load', function() {
  iFrame.contentWindow.postMessage({
    eventType: 'populateCode',
    language: "{{this.codeLang}}",
    files: [{
      "name": "file.{{this.codeLang}}",
      "content": "{{this.codeLang}}"
    }]
  }, "*");
});

它会更改 DModal 中的 iframe 以包含代码的语言和内容。但是,它告诉我 iFramenull,因此无法向其添加 addEventListener
我试过这个:

<template>
  <DButton @translatedLabel="Show Modal" @action={{this.showModal}} />

  {{#if this.modalIsVisible}}
    <DModal @title="Code Compiler" @closeModal={{this.hideModal}}>
      <p>Code: {{this.getCode}}</p>
      <iframe
       frameBorder="0"
       height="450px"
       src="https://onecompiler.com/embed/{{this.codeLang}}"
       width="100%"
       id="oc-editor"
       title="OneCompiler Code Editor"
       listenToEvents="true">
      </iframe>
      <script>
        let iFrame = document.getElementById('oc-editor');
        iFrame.addEventListener('load', function() {
          iFrame.contentWindow.postMessage({
            eventType: 'populateCode',
            language: "{{this.codeLang}}",
            files: [{
              "name": "file.{{this.codeLang}}",
              "content": "{{this.codeLang}}"
            }]
          }, "*");
        });
      </script>
    </DModal>
  {{/if}}
</template>

但这也不起作用。有什么办法可以做到吗?


仓库链接:

看起来您正在使用 gjs,因此您可以使用 glimmer 函数,而不是尝试处理 DOM 渲染和竞态条件。将 glimmer {{on}} 修饰符 添加到 iframe 元素,并让您的 on loaded 函数在其上触发。

@action
onIframeLoaded() {
  ...
}

...

<iframe {{on "load" this.onIframeLoaded}}
2 个赞

竟然……有这个!?哇,我试试。

嗯……我遇到了这个错误:

编译错误:错误:/discourse/theme-9718/discourse/components/show-onecompiler: 第 18 行的解析错误:
...   {{on "load" this.onIframeLoaded()}}>
-----------------------^
预期为 'ID',但得到 'INVALID' (discourse/components/show-onecompiler.gjs)

代码:

@action
  onIframeLoaded() {
    let iFrame = document.getElementById('oc-editor');
    iFrame.contentWindow.postMessage({
      eventType: 'populateCode',
      language: "{{this.codeLang}}",
      files: [
        {
          "name": "file.{{this.codeLang}}",
          "content": "{{this.codeLang}}"
        }
      ]
    }, "*");
    return;
  }


  <template>
    <DButton
      @translatedLabel="Show Modal"
      @action={{this.showModal}}
    />

    {{#if this.modalIsVisible}}
      <DModal @title="Code Compiler" @closeModal={{this.hideModal}}>
        <p>Code: {{this.getCode}}</p>
        <iframe
          frameBorder="0"
          height="450px"
          src="https://onecompiler.com/embed/{{this.codeLang}}"
          width="100%"
          id="oc-editor"
          title="OneCompiler Code Editor"
          listenToEvents="true"
          {{on "load" this.onIframeLoaded()}}>
        </iframe>
      </DModal>
    {{/if}}
  </template>

啊,我弄错了示例。应该是 {{on \"load\" this.onIframeLoaded}},没有括号,因为它应该是一个函数引用。

我已经编辑了我的回复。

3 个赞

嗯……ESLint 提示 Error: 74:13 error 'on' is not defined。文档中没有提到导入,因为它是一个修饰符。
我将 event 添加为 onIframeLoaded 的参数,因为文档就是这么做的。

添加 import { on } from “@ember/modifier”; 应该就能解决问题。
查看 Discourse 源代码是个好主意。那里有现成的代码,是学习的好地方。

2 个赞

另请参阅 GitHub - discourse/all-the-pluginsGitHub - discourse/all-the-themes

3 个赞