I have 2 lit-element components. The parent content is :
<s-sortablelist>
${this.renderChildren()}
</s-sortablelist>
The renderChildren
function is looping over an array property children = [1, 2]
and creating <div>
elements. The rendered page might be something like :
<s-sortablelist>
<div id="1"></div>
<div id="2"></div>
</s-sortablelist>
The sortablelist component allows the user to reorder the <div>
tags using drag and drop. After dnd, the rendered layout might become (2 and 1 are reverted) :
<s-sortablelist>
<div id="2"></div>
<div id="1"></div>
</s-sortablelist>
After the user changed the order, if I change the property children=[3,4]
, the result is different from my expectations :
So my question is how is it supposed to work ? If the children array changes, because it is a property, the parent component will render.
I'm expecting also the sotablelist
component to be rerendered, but why would I have extra children from a previous render?
You can't mutate the DOM under control of lit-html this much. lit-html places comment nodes into the DOM to keep track of where the dynamic template parts are, and by moving elements around you're breaking the bookkeeping.
The right way to do this is to not move nodes in the drag and drop operation, but right before you would have actually changed the DOM, instead change the data that rendered the DOM. Then lit-html can render the list on the new order, but keep all the comment node and other internal data in sync.