来自父级 Promise 的子级 属性

child property from parent Promise

我想为我的项目创建一个导航组件。 shell 获取带有章节信息的 json,这些被传递给 nav-element,后者递归调用自身以呈现导航树。

shell.js

import { LitElement, html, css } from 'lit-element';
import {until} from 'lit-html/directives/until.js';
import './nav-element.js';

export class Shell extends LitElement {
  static get properties() {
    return {
      configjson : { type: Array }
    };
  }

  constructor() {
    super();
    this.configjson = fetch('./src/convertjson_test.json').then(res => res.json());
  }

  render() {
    return html`
        <main>
            some content
            <nav-element .chapters=${until(this.configjson, [])} root></nav-element>
        </main>
    `;
  }
}
customElements.define('shell', Shell);

导航-element.js

import { LitElement, html, css } from 'lit-element';
import {until} from 'lit-html/directives/until.js';
import {repeat} from 'lit-html/directives/repeat.js';

export class NavElement extends LitElement {
  static get properties() {
    return {
        chapters: {type: Array},
        root: {type: Boolean} //to mark the root node
    };
  }

  static get styles() {
    return css`
        .navheader {
            display: none;
        }

        .navheader[active] {
            display: block;
        }
    `;
  }

  render() {
    return html`
        <div class="navHeader" ?active="${this.root}">header</div>
        ${until(repeat(this.chapters, (chapter) => chapter.pos, (chapter) => html`<div>${chapter.n}<nav-element .chapters=${chapter.c}></nav-element></div>`))}
    `;
  }
}
customElements.define('nav-element', NavElement);

问题是,configjson Promise 作为 属性 传递并且在调用 nav-element 时尚未解决,所以我得到错误:

Uncaught (in promise) TypeError: this.chapters is undefined

搜索了所有 lit-elementlit-html 文档,until 指令解决了 shell 中的问题,但未解决 nav-element 中的问题。 相同的编码模式在 Polymer 2 中运行良好(&3,尽管使用 ajax 而不是 fetch)。有谁知道如何仅使用 lit-element 解决这个问题?

NavElement 的构造和 chapters 属性 的赋值之间有一个时间范围,其中 chaptersundefined。在组件本身而不是 Shelluntil 指令中初始化 chapters 可能是安全的,或者至少在模板中提供后备值:

export class NavElement extends LitElement {
  static get properties() {
    return {
        chapters: {type: Array},
        // ...
    };
  }

  constructor() {
    super();
    this.chapters = [];
  }

  // or

  render() {
    return html`
      ...
      ${repeat(this.chapters || [], chapter => ...)}
    `;
  }
}

此外,您已经(正确地)将 chapters 属性 声明为 Array 但您将 repeat 指令包装在 until(好像是 Promise 我猜?)。这里有两件事正在发生:

  • repeat() 将 returns 称为 DirectiveFn 而不是 until 期望的 Promise。如果 chaptersPromise,那么组合 untilrepeat 的正确方法应该是:

    until(
      this.chaptersPromise.then(chapters => repeat(chapters, chapter => html`...`)),
      html`Loading...`,
    )
    

    但是...

  • chapters 不是 Promise:父组件中的 until 调用解析它并传递结果。

至于 Shell 组件:until 以这种方式使用应该有效,但其预期用途是

Render placeholder content until the final content is available

[from lit-html docs]

要充分利用它,请使用它来临时呈现加载模板而不是 <nav-element>:

render() {
  return html`
    ${until(
      this.configJson.then(chapters => html`<nav-element .chapters=${chapters}></nav-element>`),
      html`Loading chapters`,
    )}
  `;
}

此外,没什么大不了的,但是这里 configJson 属性 被声明为 Array 但实际上是 Promise.