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 で作業しているようですので、DOM レンダリングや競合状態の回避を試みる代わりに、Glimmer 関数を使用できます。Glimmer の {{on}} 修飾子 を iframe 要素に追加し、onIframeLoaded 関数をそれに紐づけてください。

@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

Hmm… ESLint で Error: 74:13 error 'on' is not defined と表示されます。ドキュメントには、それがモディファイアであるため、インポートについての言及がありません。
ドキュメントで eventonIframeLoaded のパラメータとして追加されていたため、私も追加しました。

import { on } from "@ember/modifier"; を追加すると、この問題は解決するはずです。

Discourse のソースコードを確認することをお勧めします。既存のコードから学ぶのに良い場所です。

「いいね!」 2

GitHub - discourse/all-the-plugins および GitHub - discourse/all-the-themes も参照してください。

「いいね!」 3