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