【发布时间】:2020-08-18 17:51:11
【问题描述】:
我想构建一个 html 自定义元素,它的行为应该与原生 <select> 元素几乎相同,但此外,它还必须在每次属性或子节点更改时调用某个更新函数。 (背景故事:这是在 elm 框架内使用 bootstrap-select 元素的必要步骤。另见 my last question。)
使用 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。这是因为我的自定义元素正在被引导(和引导选择)css/js 设置样式/增强,它只查看普通 DOM。正如我刚刚了解到的,这排除了
slot元素,因为这些是影子 DOM 特定的。 - 我的自定义元素必须完全响应更改(添加/删除子注释、更改属性)。这是因为我计划在虚拟 DOM 中使用该元素(在我的例子中是 elm,但它也应该与 react 一起使用)。
附录
我对@987654333@的定义:
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>
`;
}
}
【问题讨论】:
标签: javascript typescript polymer custom-element lit-element