【问题标题】:LitElement rendering template without values没有值的 LitElement 渲染模板
【发布时间】:2018-06-20 22:01:58
【问题描述】:

我有一个简单的例子来展示我所看到的:https://stackblitz.com/edit/lit-element-example-3pdnwk?file=index.js

基本上,当第一个子元素呈现时,text 属性设置正确。但是在第二次渲染中,text 属性首先是 undefined,然后更新为正确的值。

这打破了依赖_firstRendered() 为属性分配正确值的能力。

我真的在这里做点什么吗?

更新:这是使用lit-html documentation中提供的类似方法的更好示例:https://stackblitz.com/edit/lit-element-issue?file=index.js

【问题讨论】:

    标签: javascript polymer lit-element


    【解决方案1】:

    我真的在这里做点什么吗?

    也许? :) 希望你能帮助我理解你为什么选择你的实现,我可以进一步研究它。

    我坚持的部分是为什么您要像这样在父元素中创建和替换子元素:

    this._child = html`<child-element text="${text1}"></child-element>`;
    

    据我目前了解,该代码使用 lit-html 辅助函数来创建 lit-html TemplateResult。然后在超时回调中将其替换为另一个:

    this._child = html`<child-element text="${text2}"></child-element>`;
    

    因此,您的代码不只是重新绘制更改的内容(字符串),而是创建一个新的 TemplateResult 并重新绘制它。这还会再次调用子元素构造函数,并导致文本节点暂时未定义,如您所述。这是添加到您的 impl 的控制台输出,以显示何时为父子和子调用构造函数和渲染函数:

    https://stackblitz.com/edit/lit-element-example-ftlbz7?file=index.js

    通过检查 DOM 树,您的示例会生成以下 DOM 结构:

    <parent-element>
      #shadow-root
        <div>
          <child-element>
            #shadow-root
              <div>
    

    假设我需要生成相同的 DOM 结构并具有相同的文本节点更新以响应超时回调,我可能会在父渲染函数中处理它:

    _render({ parenttext }) {
      return html`<div><child-element text="${parenttext}"></child-element></div>`;
    }
    

    这确保子构造函数只被调用一次,并且只有实际更改的数据才会被重绘。

    如果我理解正确的话,这就是 lit-element 的设计用途(将应用程序或元素的渲染表示为其数据的函数)。这样我们就可以依靠浏览器来重绘对数据的任何更改。这理论上应该更快(虽然我没有测试过)。

    此处的代码示例:

    https://stackblitz.com/edit/lit-element-example-exrlxw?file=parent-element.js

    Lmk 我在你的测试中遗漏了什么,我可以进一步研究。


    编辑添加:

    我注意到覆盖 _shouldRender 以防止使用未定义的道具渲染元素会阻止使用未定义的道具渲染元素,但它没有修复 _firstRendered,它在道具未定义时仍在触发。

    _firstRendered_didRender 不同,不是作为_render 的结果而专门调用的;它是called from the ready() callback,继承自Polymer's properties-changed mixin。在 Polymer 中,ready() 在元素添加到 DOM 时触发。我认为到那时应该初始化属性,所以这仍然很奇怪。

    无论如何,这意味着可以创建一个从不渲染的元素(即 _shouldRender 总是返回 false),但 _firstRendered 仍然会触发。哈哈。示例:https://stackblitz.com/edit/lit-element-first-rendered?file=index.js

    老实说,我不确定该怎么做。当我从文档中阅读更多内容时,我会在 lit-element github 上提出一个问题(或者你可以,如果你先到那里的话)。

    【讨论】:

    • 我感兴趣的不是实现,而是更多的副作用。我的示例是我当前代码中更复杂示例的最简单版本。据我了解,lit-html 应该允许组合 TemplateResults(请参阅polymer.github.io/lit-html/guide/…)。奇怪的是,对于第一次渲染,text 属性设置正确,但是在第二次渲染中,子元素必须被渲染两次,而第一次没有正确设置 text 属性。这似乎阻碍了_firstRendered()
    • 我已经根据显示相同行为的 lit-html 文档使用第二个示例更新了问题。
    • 您知道,我正在调查此事。感谢您提供额外的信息,现在它更有意义了。我正在研究一些细节——应该如何使用 lit-element 进行组合,当你想用原生元素和自定义元素组合时它是否不同,等等。我还注意到 firstRendered 实际上并不依赖于渲染。
    • 用与我上面的评论相关的新信息更新了我的答案
    【解决方案2】:

    0.6.0-dev.5开始,这不再是问题

    【讨论】:

      猜你喜欢
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      • 2019-05-15
      • 2016-04-23
      • 2018-01-10
      • 2011-06-21
      • 2013-07-10
      相关资源
      最近更新 更多