Искам да създам персонализиран html елемент, който трябва да се държи почти идентично с основния елемент <select>
, но освен това трябва да извиква определена функция за актуализиране всеки път, когато се промени атрибут или дъщерен възел. (история: Това е необходима стъпка за използване на елемента bootstrap-select вътре в elm рамка. Вижте също последния ми въпрос.)
Използвайки рамката LitElement, успях да създам работещ потребителски елемент (наречен <lit-select>
), подобен на описанието по-горе. Но за съжаление не успях да го накарам да приема html <option>
или <optgroup>
елементи като дъщерни. Вместо това потребителят трябва да предаде списъка с опции към определен атрибут като json кодиран низ.
Тоест, вместо да се обадите
<lit-select>
<option>foo</option>
<option>bar</option>
</lit-select>
потребителят трябва да се обади
<lit-select items='["foo", "bar"]'></lit-select>
По какъв начин трябва да променя дефиницията си за <lit-select>
, за да направя възможно първото повикване? Знам за елемента <slot>
, но за съжаление този елемент не е разрешен в <select>
, така че браузърът просто го изтрива.
Благодаря ви предварително!
Актуализация 1
Всъщност има някои ограничения, които правят проблема по-предизвикателен, отколкото си мислех в началото:
- Трябва да избягвам shadow DOM. Това е така, защото персонализираният ми елемент се оформя/подобрява от bootstrap (и bootstrap-select) css/js, които разглеждат само обикновения DOM. Както току-що научих, това изключва
slot
елементи, тъй като те са специфични за DOM в сянка. - Моят персонализиран елемент трябва да отговаря напълно на промените (добавяне/премахване на дъщерни бележки, промяна на атрибути). Това е така, защото планирам да използвам елемента във виртуален DOM (elm в моя случай, но трябва да работи и с реакция).
Приложение
Моето определение за <lit-select>
:
import { LitElement, html, customElement, property } from 'lit-element';
import * as $ from 'jquery';
import 'bootstrap';
import 'bootstrap-select';
@customElement('lit-select')
export class LitSelect extends LitElement {
@property({ type : Array }) items = []
updated() {
$(this).find(".selectpicker").selectpicker('refresh');
}
createRenderRoot() {
return this;
}
private renderItem(item: string) {
return html`
<option>
${item}
</option>
`;
}
render() {
return html`
<select class="selectpicker" data-live-search = "true">
${this.items.map(item => this.renderItem(item))}
</select>
`;
}
}