Dog*_*oku 5 html css dom web-component custom-element
我目前正在使用自定义元素(Web 组件)实现数据表元素。表格可以具有用于呈现每一行的不同类型的单元格(文本、数字、日期等)。
例如
<my-table>
<my-table-cell-text column="name"></my-table-cell-text>
<my-table-cell-date column="dob" format="YYYY-MM-DD"></my-table-cell-date>
<my-table-cell-number column="salary" decimals="2"></my-table-cell-number >
</my-table>
Run Code Online (Sandbox Code Playgroud)
我还有一个MyTableCell所有单元格元素都扩展的类。这适用于共享通用功能,但样式可能很麻烦,因为每个单元格类型都是它自己的 html 标签。目前,我在扩展时添加了一个 css 类MyTableCell,但为了论证,可以说我不想这样做。
理想的解决方案是能够扩展自定义元素,使用is关键字,例如<my-table-cell is="my-table-cell-text">,但只允许内置 html 元素。
我可以想到解决这个问题的 3 种方法:
具有类似于 的语法<input type="">,但需要做更多的工作,因为您不再扩展基类,而是创建相同元素的变体,这意味着您需要一种自定义方式来注册不同的变体,例如静态MyTableCell.registerType
一种可组合的方法,我将渲染器元素 包裹<my-table-renderer-text>在通用<my-table-cell>. 这避免了自定义注册方法,但它更难编写,并导致更多元素和更多样板代码,这反过来意味着性能下降。
两者的混合,用户写入<my-table-cell type="text">和单元格在document.createElement('my-table-rendener-'+ type)内部使用类似的东西。这保留了选项 1 的更简单的语法,同时仍然避免了自定义寄存器方法,但它具有与选项 2 相同的性能影响。
你能提出更好的选择吗?我错过了什么吗?
可以做的是使用<td>定制的内置元素:
<table is="data-table>
<tr>
<td is="data-string">Bob</td>
<td is="data-date">11/1/2017</td>
<td is="data-number">44<td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
所有扩展共享相同的原型祖先。例子:
//common cell
class DataCell extends HTMLTableCellElement {...}
//typed cell
class StringCell extends DataCell {
renderContent() { ... }
}
customElements.define( 'data-string', StringCell, { extends: 'td' } )
Run Code Online (Sandbox Code Playgroud)
通过这种方式,所有单元格都扩展了相同的<td>元素,共享一个共同的原型,但有自己的方法实现。
您可以覆盖共享方法,共享方法可以调用派生原型对象的特定方法。
在此处查看运行示例:
<table is="data-table>
<tr>
<td is="data-string">Bob</td>
<td is="data-date">11/1/2017</td>
<td is="data-number">44<td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
//common cell
class DataCell extends HTMLTableCellElement {...}
//typed cell
class StringCell extends DataCell {
renderContent() { ... }
}
customElements.define( 'data-string', StringCell, { extends: 'td' } )
Run Code Online (Sandbox Code Playgroud)
//table
class DataTable extends HTMLTableElement {
constructor() {
super()
console.info( 'data-table created' )
}
}
customElements.define( 'data-table', DataTable, { extends: 'table' } );
//cell
class DataCell extends HTMLTableCellElement {
connectedCallback() {
console.info( 'cell connected' )
if ( typeof this.renderContent === 'function' )
this.renderContent()
}
}
//cell string
class StringCell extends DataCell {
renderContent()
{
console.info( 'data-string render' )
this.innerHTML = '"' + this.textContent.trim() + '"'
}
}
customElements.define( 'data-string', StringCell, { extends: 'td' } )Run Code Online (Sandbox Code Playgroud)
注意:如果您不想要类型扩展,您也可以使用自定义标签来实现。这个想法是拥有一个通用原型和共享它的不同自定义元素(感谢标准原型继承)。
| 归档时间: |
|
| 查看次数: |
2030 次 |
| 最近记录: |