【问题标题】:External class call a LitElement component method (passing html template), and component method updates its html template外部类调用一个LitElement组件方法(传递html模板),组件方法更新其html模板
【发布时间】:2020-03-28 00:26:13
【问题描述】:

我需要一个由游戏逻辑组成的外部类调用 LitElement 组件,并向其传递一个 html 模板文字,该组件将使用该模板文字来更新其自己的 html 模板文字的一部分。

在下面的代码中,您将看到可以从组件内成功调用的组件方法 (navigationRender)。同样的方法也可以从外部game 类中成功调用(如console.log 所示)。但是,即使可以调用,也没有成功更新组件的html模板。

navigationRender 是否需要在firstUpdated 的范围内进行某种回调?我在这里不知所措,如果这是需要的话,那么我无论如何都不知道该怎么做......

以下是压缩成单个文件的代码。如果您单击“更改描述”按钮,那么您将看到 console.log 使用传递的 html 模板进行更新,而不是呈现的 html 文本。

<body>
  <front-end></front-end>
</body>

<script type="module">
  import { LitElement, html, css } from 'https://unpkg.com/lit-element?module';
  
  class FrontEnd extends LitElement {
    constructor() {
    super();
    this.renderDescription = html`<p>initialized - 01</p>`;
    }
    render() { 
      return [
        html`<button id="btn">Change Description</button>`,
        this.renderDescription]; 
    }
    firstUpdated() {
      this.game = new Game();
      this.navigationRender(html`<p>DESCRIPTION: So far, working when called from firstUpdated(). But what about when called from the Game class?</p>`);
      this.shadowRoot.getElementById('btn').addEventListener('click', (e) => {
        this.game.newDescription();
      });
    }
    navigationRender(description) {
      console.log(description);
      this.renderDescription = description;
      this.requestUpdate();
    }
  }
  customElements.define('front-end', FrontEnd);
  
  class Game {
    constructor() {
      this.frontEnd = new FrontEnd();
    }
    newDescription() {
      this.frontEnd.navigationRender(html`DESCRIPTION: Although the console.log verifies that this.frontEnd.navigationRender is being called and the data passed, that function is not able to actually update the this.renderDescription when called from the game class.`);
    }
  }
</script>

感谢您的帮助和建议!

【问题讨论】:

    标签: javascript oop lit-element lit-html


    【解决方案1】:

    我想通了。希望这对其他人有所帮助。

    <body>
      <front-end id="fe-id"></front-end>
    </body>
    
    <script type="module">
      import { LitElement, html, css } from 'https://unpkg.com/lit-element?module';
      
      class FrontEnd extends LitElement {
        constructor() {
        super();
        this.renderDescription = html`<p>initialized - 01</p>`;
        }
        render() { 
          return [
            html`<button id="btn">Change Description</button>`,
            this.renderDescription]; 
        }
        firstUpdated() {
          this.game = new Game();
          this.navigationRender(html`<p>So far, working when called from firstUpdated(). But what about when called from the Game class?</p>`);
          this.shadowRoot.getElementById('btn').addEventListener('click', (e) => {
            this.game.newDescription();
          });
        }
        navigationRender(description) {
          console.log(description);
          this.renderDescription = description;
          this.requestUpdate();
        }
      }
      customElements.define('front-end', FrontEnd);
      
      class Game {
        constructor() {
          // this.frontEnd = new FrontEnd();
          this.element = document.getElementById('fe-id');
        }
        newDescription() {
          this.element.navigationRender(html`<p>YAY!!  THIS WORKS!!!</p>`);
        }
      }
    </script>

    【讨论】:

    • 如果您想以更 OOP 的方式解决这个问题(并且由于 Game 还不需要了解 DOM 层),将 Frontend 作为构造函数参数传递给 Game 可能就足够了.像这样:this.game = new Game(this);this 是前端的实例。 Game 的构造函数内部this.frontEnd = frontend 第一个代码失败的原因是因为您在 Game 内部创建了一个新的 Frontend 实例(不是组件,只是一个类实例),这与您的标记在页面加载时创建的实例不同.
    猜你喜欢
    • 2022-09-18
    • 2017-06-05
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多