4


live example

Basically:

  • I place the child component inside the parent's html.

  • The child component has a property title inside the static get properties() object.

  • In the parent component, i assign the child component's title property to a private variable that is not in the static get properties() of the parent component.

  • Later, in a setTimeout inside the parent component, i change the value of the private variable.

  • The child component doesn't re-render.

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

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

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

Now, i know that if i put the _privateVariable in the static get properties() of the parent component, the child re-renders, but that's because the whole parent is re-rendering.

Once attached to the DOM, the child component is watching his title property, so it should realize that the value assigned to it changed and re-render.

I don't understand why i have to re-render the whole parent to make the child re-render.

Using the developer console and accessing the component in the DOM:

  • If i change the child component's property with javascript, the child re-renders perfectly fine, without me having to re-render the whole parent element.

  • If i edit the child component's html and manually change the attribute, the child re-renders perfectly fine, without me having to re-render the whole parent element.

What am I missing here?

dvolp
  • 43
  • 1
  • 3

2 Answers2

2

I answered on GitHub: https://github.com/Polymer/lit-element/issues/899#issuecomment-592295954

But here's a copy for other readers:

@dvolp the child component is observing its title property, but it's not observing the parent component's _privateVariable property. And without declaring _privateVariable as a LitElement property in the static properties object, the parent component isn't observing that property either.

You need to re-render the parent when you set _privateVariable because re-rendering is what sets the child's title property to the current value of _privateVariable.

The binding in here only runs on a render. If this isn't run, there's nothing else to set the title property:

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

This is exactly why you must include _privateVariable in the static properties object of the parent, so that when you set it, the parent component is notified and re-renders, which in turn sets the title property on the child component.

Justin Fagnani
  • 10,483
  • 2
  • 27
  • 37
0

In polymer, properties will be watched/observed for changes only if they are declared in static get properties() section. As you are not declaring '_privateVariable' in properties() section of parent, any changes made to it will not be injected back into the child component and hence the value won't be updated. When you change the value of '_privateVariable' after declaring it in parent, complete parent won't be reloaded its only the child component which will reload. However, if you still have any requirement to not declare the '_privateVaraible' in parent and still needs an update, you can update the variable value in child component and encapsulate the update in a function and call that function from your parent's setTimeout.

Vin
  • 161
  • 3