admin管理员组文章数量:1302374
I've created a custom select-ponent with LitElement:
import { LitElement, html } from 'lit-element';
class CustomSelect extends LitElement {
static get properties() {
return {
options: { type: Array },
selected: { type: String },
onChange: { type: Function }
};
}
constructor() {
super();
this.options = [];
}
render() {
return html`
<select @change="${this.onChange}">
${this.options.map(option => html`
<option value="${option.value}" ?selected=${this.selected === option.value}>${option.text}</option>
`)}
</select>
`;
}
createRenderRoot() {
return this;
}
}
customElements.define('custom-select', CustomSelect);
I pass in options
, selected
and onChange
as properties when I create the element. On the first render, everything works fine. All options are rendered and the selected value is reflected in the select. However, if I change selected
it doesn't seem to update the selected option. If I inspect the element with dev-tools, the selected
attribute is set correctly, but if I start querying the element for its value, it returns the wrong value.
One thing I tried is to add an id
attribute to the element via dev-tools after the select has been rendered. If I then change the selected
property on CustomSelect
, the id
attribute persists in the DOM, which says to me that the select is not re-rendered, which is what causing the issue, and why it's working on the first render.
I've tried setting the value
and selectedIndex
properties on the select-element, but it doesn't seem to affect anything in a meaningful way.
I've logged everywhere (beginning in render() and in the options-map) and all input values are correct.
I've created a custom select-ponent with LitElement:
import { LitElement, html } from 'lit-element';
class CustomSelect extends LitElement {
static get properties() {
return {
options: { type: Array },
selected: { type: String },
onChange: { type: Function }
};
}
constructor() {
super();
this.options = [];
}
render() {
return html`
<select @change="${this.onChange}">
${this.options.map(option => html`
<option value="${option.value}" ?selected=${this.selected === option.value}>${option.text}</option>
`)}
</select>
`;
}
createRenderRoot() {
return this;
}
}
customElements.define('custom-select', CustomSelect);
I pass in options
, selected
and onChange
as properties when I create the element. On the first render, everything works fine. All options are rendered and the selected value is reflected in the select. However, if I change selected
it doesn't seem to update the selected option. If I inspect the element with dev-tools, the selected
attribute is set correctly, but if I start querying the element for its value, it returns the wrong value.
One thing I tried is to add an id
attribute to the element via dev-tools after the select has been rendered. If I then change the selected
property on CustomSelect
, the id
attribute persists in the DOM, which says to me that the select is not re-rendered, which is what causing the issue, and why it's working on the first render.
I've tried setting the value
and selectedIndex
properties on the select-element, but it doesn't seem to affect anything in a meaningful way.
I've logged everywhere (beginning in render() and in the options-map) and all input values are correct.
Share asked Apr 25, 2019 at 21:45 CaptainBarefootCaptainBarefoot 811 silver badge3 bronze badges 2- I'd like to add that in the real application, the select is being rendered in a td in a table. When the select is changed, I fire a state change through Redux that changes the state of some values in the table row, which causes a render of all the rows. Everything else renders correctly. Could it be that since the select is causing the change, its internal state gets stuck somehow? – CaptainBarefoot Commented Apr 26, 2019 at 13:28
- Adding some extra information: 1. The table is initialized like this. It's sorted on "Status". The selected option is reflected correctly. 2. I change the option like this. This updates the state, and in turn rerenders the rows. The other columns updates correctly, but the select is displaying the incorrect value, even though the option has the correct value selected. The old row is sorted away since we sort on that same column, but it's still displaying the state of that old select on the new row. – CaptainBarefoot Commented Apr 27, 2019 at 13:10
2 Answers
Reset to default 4Working example:
https://stackblitz./edit/litelement-testt-csgkmc
Fixed using the repeat directive.
import { repeat } from 'lit-html/directives/repeat';
${repeat(this.sortedRows, e => e, row => html`
<tr>
${row.map((cell, index) => html`
<td>${this.onRenderCell(cell, index, row)}</td>
`)}
</tr>
`)}
https://github./Polymer/lit-element/issues/805#issuement-530461555
It's I think, rendering time and selected property definition on onChange
functions timing conflict. So, better to assign a setTimeout
in onChange
then it's working properly. At my example at below link. I faced the same when I remove setTimeout
Also, you don't need to declare onChange
as function at properties.
Demo
static get properties() {
return {
options: { type: Array },
selected: { type: String }
};
}
constructor() {
super();
this.options = [{value:1, text:"ben"},{value:2, text:"sen"},{value:3, text:"oo"},{value:4, text:"biz"},{value:5, text:"siz"},{value:6, text:"onlar"}];
this.selected = 3
}
render() {
return html`
<select id="sel" @change="${this.onChange}">
${this.options.map(option => html`
<option value="${option.value}" ?selected=${this.selected === option.value}>${option.text}</option>
`)}
</select>
<button @click="${this.changeSelected}">Random chage selected option</button>
`;
}
onChange(x){
setTimeout(()=>{
this.selected = this.shadowRoot.querySelector('#sel').value
console.log('Selected -->', this.selected );
},300)
}
changeSelected(){
this.selected = (this.options[Math.floor(Math.random() * 6)].value)
console.log(this.selected)
}
本文标签: javascriptCustom litelement select not rerendering correctlyStack Overflow
版权声明:本文标题:javascript - Custom litelement select not rerendering correctly - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741675847a2391878.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论