例如
<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>
我还有一个所有单元格元素都扩展的MyTableCell类.这适用于共享通用功能,但样式可能很痛苦,因为每个单元格类型都是自己的html标记.目前,我在扩展MyTableCell时添加了一个css类,但是出于参数的考虑,让我说我不想这样做.
理想的解决方案是能够使用is关键字扩展自定义元素,例如< my-table-cell is =“my-table-cell-text”>,but that’s only allowed for built in html elements.
>具有类似于< input type =“”>的语法,但这样做的工作要多得多,因为您不再扩展基类,而是创建相同元素的变体,这意味着您需要一种自定义的注册方式不同的变体,类似于静态MyTableCell.registerType
>一种可组合的方法,我将一个渲染器元素< my-table-renderer-text>包装在一个通用的< my-table-cell>中.这避免了自定义寄存器方法,但它更难编写并导致更多元素和更多样板代码,这反过来意味着性能损失.
>两者的混合,用户写的< my-table-cell type =“text”>并且单元格在内部使用了document.createElement(‘my-table-rendener-‘type)之类的东西.这保留了选项1的更简单的语法,同时仍然避免使用自定义寄存器方法,但它具有与选项2相同的性能影响.
你能建议更好的选择吗?我错过了什么吗?
解决方法
<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>
所有扩展都共享相同的原型祖先. v0示例:
//common cell var cellProto = Object.create( HTMLTableCellElement.protoype ) cellProto.sharedMethod = function () { ... } //typed cell var cellStringProto = Object.create( cellProto ) cellStringProto.specificMethod = function () { ... } cellStringProto.sharedMethod = function () { ... } document.registerElement( 'data-string',{ prototype: cellStringProto,extends: 'td' } )
这样,所有细胞都延伸相同的细胞.元素,共享一个共同的原型,但有自己的方法实现.
您可以覆盖共享方法,而共享方法可以调用派生原型对象的特定方法.
请在此处查看运行示例:
//table var tableProto = Object.create( HTMLTableElement.prototype ) tableProto.createdCallback = function () { console.info( 'data-table created' ) } document.registerElement( 'data-table',{ prototype: tableProto,extends: 'table' } ) //cell var cellProto = Object.create( HTMLTableCellElement.prototype ) cellProto.createdCallback = function () { console.info( 'cell created' ) } cellProto.attachedCallback = function () { console.info( 'cell attached' ) if ( typeof this.renderContent === 'function' ) this.renderContent() } //cell string var cellStringProto = Object.create( cellProto ) cellStringProto.createdCallback = function () { console.info( 'data-string created' ) } cellStringProto.renderContent = function () { console.info( 'data-string render' ) this.innerHTML = '"' + this.textContent.trim() + '"' } document.registerElement( 'data-string',extends: 'td' } )
table { border-collapse: collapse ; } td,th { border: 1px solid gray ; padding: 2px }
<h4>Test Table Extension v0</h4> <table is="data-table"> <tr> <th>Id <th>Name <th>Age <tr> <td>1 <td is="data-string">An <td>20 <tr> <td>2 <td is="data-string">Bob <td>31
注意:如果您不想要类型扩展,也可以使用自定义标记.我们的想法是拥有一个共同的原型和共享它的不同自定义元素(感谢标准的原型继承).