Closed robhicks closed 6 years ago
i try it here: https://codepen.io/pinguxx/pen/VXbPVB?editors=0010
seems to work, can you reproduce your problem in that pen?
I can reproduce it here: https://codepen.io/robhicks/pen/GxmmRj?editors=1111
ah since you are passing the same object again and again to the wire, its just reusing the options elements again and again, if you give the employeelist a particular id and pass that to the wire, then that will create new option elements each time, or just dont pass li to wire and that will also do it
wire(li, ':id' + this.someuniqueattr)`...`
or just
wire()`...`
@robhicks I think @pinguxx is right, if you use same weak reference wire will give you always the same resulting node. The :id
part of the signature might help but in your very specific case, the cache is your issue: no matter how many options you create, the resulting node is always one related to that entry in the cache list.
You have two solutions, accordingly to your needs:
wire()
without passing any li
. Be aware that in this way you'll lose the currently selected option if a render is called again. In your case, since you render on connected only, this should not be an issue.wire(this, ':option-' + i)
. This will weakly relate each option to its Custom Element owner, and it will have 1:1 relation per option index. You could use a JSON version of the data if you really want to have perfect unique option but that's usually not necessary at all, just some overhead.I've noticed that you use i18n via this.t('controlled_vocabulary')
. I'd like to remind you that with hyperHTML
you can define intents.
hyperHTML.define('i18n', (id) => {
return i18n.t(id) || '';
});
Once you've done that upfront, at application level, you can write templates like this:
<div
id="controlledVocabulary-wrapper"
class="${this.field.authorityList.listType === 'controlledVocabulary' ? '' : 'hidden'}"
>
<div id="left"></div>
<div id="right">
<div id="cv-wrapper">
<label for="cv-type">${{i18n: 'controlled_vocabulary'}}</label>
<select id="cv-type" name="cv-type" value="${this.field.authorityList.uri}" onchange="${this}">
<option value="" default>${{i18n:'cv_select_type'}}</option>
${cvList.map((li, i) => wire(this, ':option-' + i)`
<option value="${li.uri}" selected="${this.field.authorityList.uri === li.uri ? true : null}">
${li.en.displayName}
</option>`)}
</select>
</div>
</div>
</div>
edit this assuming you have a centralized i18n object instead of entries per each component, of course.
@pinguxx Thanks!
@WebReflection Thanks Andrea. Your explanation really helps. BTW, I'm just getting my feet wet with hyperHTML. A couple of us in our organization are trying to champion it's use. Currently, we're a big Polymer shop. Some of us are trying to break that trend and go native. Hopefully, that way we won't have to pinch our noses and use lit-html.
@robhicks happy to help doing that. Just in case, remember there is hyper.Component to help CustomElements-less projects, and HyperHTMLElement to help with Custom Elements projects 😉
I have a web component that is repeated a number of times (possibly up to 100).
Each component gets a list of options for a select. The select looks like this:
I can verify that the options are available through the option console.log. And the return statement returns the option elements. Nevertheless, the option elements never never get inserted into the DOM.
The options render fine when the number of components is smaller (less than 5).
Any ideas why?