كيفية الوصول إلى المتغيرات المُتتبعة في 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}}"
    }]
  }, "*");
});

يقوم بتغيير الإطار المضمن (iframe) الموجود في DModal لتضمين لغة المحتوى البرمجي ومحتواه. ومع ذلك، فإنه يخبرني أن iFrame هو null، لذلك لم يتمكن من إضافة 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)

هذا… موجود حقًا؟! واو، سأجربه.

حسنًا… لقد واجهت هذا الخطأ:

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)

الكود:

@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 إعجابات

هممم… يقول خطأ: 74:13 خطأ 'on' غير معرف في ESLint. ولا تذكر المستندات أي استيراد لأنه مُعدِّل.
لقد أضفت event كمعامل لـ onIframeLoaded لأن المستندات فعلت ذلك.

أضف import { on } from "@ember/modifier"; ويجب أن يعمل هذا.
من الجيد إلقاء نظرة على الكود المصدري لـ Discourse. إنه مكان جيد للتعلم من خلال الكود الموجود.

إعجابَين (2)

انظر أيضًا GitHub - discourse/all-the-plugins و GitHub - discourse/all-the-themes

3 إعجابات