Я хочу создать настраиваемый элемент html, который должен вести себя почти так же, как собственный элемент <select>
, но, кроме того, он также должен вызывать определенную функцию обновления каждый раз, когда изменяется атрибут или дочерний узел. (предыстория: это необходимый шаг для использования элемента bootstrap-select внутри вяза framework. См. также мой последний вопрос.)
Используя фреймворк 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
На самом деле есть некоторые ограничения, которые делают проблему более сложной, чем я думал сначала:
- Я должен избегать теневого DOM. Это связано с тем, что мой пользовательский элемент стилизован / улучшен с помощью bootstrap (и bootstrap-select) css / js, которые смотрят только на обычную DOM. Как я только что узнал, это исключает
slot
элементов, поскольку они специфичны для теневой DOM. - Мой настраиваемый элемент должен полностью реагировать на изменения (добавление / удаление дочерних заметок, изменение атрибутов). Это связано с тем, что я планирую использовать элемент внутри виртуальной DOM (в моем случае вяз, но он также должен работать с реакцией).
Приложение
Мое определение <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>
`;
}
}