¿Acceder a variables rastreadas en VanillaJS?

Tengo este fragmento de código:

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}}"
    }]
  }, "*");
});

Cambia el iframe que está en un DModal para incluir el lenguaje y el contenido del código. Sin embargo, me dice que iFrame es null, por lo que no pudo agregar addEventListener a él.
He intentado esto:

<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>

Pero eso tampoco funcionó. ¿Hay alguna manera de hacerlo?

Enlace al repositorio:

Parece que estás trabajando en gjs, así que puedes usar funciones de glimmer en lugar de intentar solucionar problemas de renderizado DOM y condiciones de carrera. Agrega el modificador {{on}} de glimmer con el elemento iframe y haz que tu función on loaded se active en él.

@action
onIframeLoaded() {
  ...
}

...

<iframe {{on "load" this.onIframeLoaded}}
2 Me gusta

¡¿Eso… existe!? Vaya, lo intentaré.

Mmm… tengo este error:

Compile error: Error: /discourse/theme-9718/discourse/components/show-onecompiler: Parse error on line 18:
...   {{on "load" this.onIframeLoaded()}}>
-----------------------^
Expecting 'ID', got 'INVALID' (discourse/components/show-onecompiler.gjs)

Código:

@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>

Ah, me equivoqué en mi ejemplo. Debería ser {{on \"load\" this.onIframeLoaded}}, sin paréntesis, ya que debería ser una referencia a una función.

He editado mi respuesta.

3 Me gusta

Hmm… dice que Error: 74:13 error 'on' no está definido en ESLint. Y la documentación no menciona ninguna importación porque es un modificador.
Añadí event como parámetro a onIframeLoaded porque la documentación lo hizo.

Agrega import { on } from \"@ember/modifier\"; y esto debería funcionar.
Es una buena idea mirar el código fuente de Discourse. Es un buen lugar para aprender con código existente.

2 Me gusta

Ver también GitHub - discourse/all-the-plugins y GitHub - discourse/all-the-themes

3 Me gusta