我正在try 学习如何使用Web组件创建自定义表,并try 使用getter和setter在我的自定义元素上定义属性.下面是一个非常简单的表,其中有一列,以及一个具有line_number
属性的定制行元素.通过调用setter并将值放入适当的元素中,创建自定义表,然后设置line_number
就可以正常工作.但是,如果定制表的构造函数设置了line_number
,如下面的serial-log-setter-broken
中所示,则不会调用该设置器,并且看起来已被删除(稍后try 调用它不会产生任何效果).
customElements.define('serial-log-setter-broken', class extends HTMLElement {
constructor() {
super()
this.attachShadow({
mode: 'open'
}).innerHTML = `
<table>
<thead>
<tr>
<th>Line Number</th>
</tr>
</thead>
<tbody></tbody>
</table>`
this.rows = []
for (let i = 0; i < 4; ++i) {
this.rows[i] = document.createElement('tr', {
is: 'serial-log-entry'
})
// .line_number's setter isn't called here, and seems to be deleted instead
this.rows[i].line_number = i + 1
this.shadowRoot.querySelector('tbody').appendChild(this.rows[i])
}
}
})
customElements.define('serial-log-setter-working', class extends HTMLElement {
constructor() {
super()
this.attachShadow({
mode: 'open'
}).innerHTML = `
<table>
<thead>
<tr>
<th>Line Number</th>
</tr>
</thead>
<tbody></tbody>
</table>`
this.rows = []
for (let i = 0; i < 4; ++i) {
this.rows[i] = document.createElement('tr', {
is: 'serial-log-entry'
})
this.shadowRoot.querySelector('tbody').appendChild(this.rows[i])
}
}
})
customElements.define('serial-log-entry', class extends HTMLTableRowElement {
constructor() {
super()
this.innerHTML = '<td>1</td>'
this._line_number_cell = this.querySelector('td')
}
get line_number() {
return Number(this._line_number_cell.textContent)
}
set line_number(v) {
console.log('Setter called')
this._line_number_cell.textContent = Number(v)
}
}, {
extends: 'tr'
})
console.log('This will print nothing')
document.getElementsByTagName('serial-log-setter-broken')[0].rows.forEach((v, i) => {
v.line_number = i + 1
})
console.log('This will print "Setter called" 4 times')
document.getElementsByTagName('serial-log-setter-working')[0].rows.forEach((v, i) => {
v.line_number = i + 1
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Setter overwritten</title>
</head>
<body>
<serial-log-setter-broken></serial-log-setter-broken>
<serial-log-setter-working></serial-log-setter-working>
</body>
</html>
为什么setter在Web组件外部使用时可以工作,但在Web组件内部使用时会被删除?
注:serial-log-setter-broken
和serial-log-setter-working
几乎相同,但在是否使用line_number
定位器方面有所不同.