当 属性 被 parent 修改时,Polymer/Lit-element、child 组件不会 re-render

Polymer/Lit-element, child component doesn't re-render when the property is modified by the parent


live example

基本上:

//inside parent component
render(){
 return html`
   <child-component title="${this._privateVariable}"></child-component>
 `
}

constructor(){
 super();
 this._privateVariable = 'lore ipsum'

 setTimeout(()=>{
  this._privateVariable = '123455667'
 }, 10000)
}

现在,我知道如果我将 _privateVariable 放在 parent 组件的 static get properties() 中,child re-renders,但那是因为整个 parent 是 re-rendering.

一旦附加到 DOM,child 组件正在监视他的标题 属性,因此它应该意识到分配给它的值发生了变化 re-render。

我不明白为什么我必须 re-render 整个 parent 来制作 child re-render.

使用开发人员控制台并访问 DOM 中的组件:

我在这里错过了什么?

在 polymer 中,只有在 static get properties() 部分中声明的属性才会 watched/observed 更改。由于您没有在父组件的 properties() 部分中声明“_privateVariable”,因此对其所做的任何更改都不会注入到子组件中,因此该值不会更新。 当您在父组件中声明“_privateVariable”后更改它的值时,完整的父组件不会重新加载,它只会重新加载子组件。 但是,如果您仍然需要不在父组件中声明“_privateVaraible”并且仍然需要更新,您可以更新子组件中的变量值并将更新封装在一个函数中,然后从父组件的 setTimeout 中调用该函数。

我在 GitHub 上回答:https://github.com/Polymer/lit-element/issues/899#issuecomment-592295954

但是这里有一份给其他读者的副本:

@dvolp child 组件正在观察它的标题 属性,但它没有观察 parent 组件的 _privateVariable 属性。并且没有在静态属性 object 中将 _privateVariable 声明为 LitElement 属性,parent 组件也没有观察到 属性。

您需要在设置 _privateVariable 时 re-render parent 因为 re-rendering 是将 child 的标题 属性 设置为当前_privateVariable 的值。

此处的绑定仅在渲染上 运行s。如果这不是运行,那么就没有别的设置标题了属性:

//inside parent component
render(){
 return html`
   <child-component title="${this._privateVariable}"></child-component>
 `
}

这正是为什么您必须在 parent 的静态属性 object 中包含 _privateVariable 的原因,以便在您设置它时通知 parent 组件并且 re-renders,它又在 child 组件上设置标题 属性。