Litelement - Table 排序呈现错误的值
Litelement - Table sorting renders wrong values
我正在尝试根据 Lit 元素中的值对 HTML table 进行排序。但是,我 运行 遇到了我的组件的问题。这是我的概述 table;
问题
在此应用程序中,您需要能够对每个 table header 进行排序。但是,被视为 'done' 的项目需要移至 table 的底部。每当我将项目标记为已完成时,我的问题就会出现。在下面的示例中,我会将最重要的待办事项(任务:123)标记为已完成。预期的行为是待办事项被移动到 table 的底部并启用了它的复选框。不过目前还不是这个结果。
如您所见,任务为 123 的待办事项已移至底部。但是,任务 456 的待办事项也标记了它的复选框。这不是我们想要的行为,我不知道是什么原因造成的。您还可以看到颜色不正确(这是一些样式,向您显示正在保存已更改的待办事项,黄色 = 保存,绿色 = 保存,红色 = 错误)。
我尝试过的东西
因为我不知道究竟是什么导致了这个问题,所以我不知道我应该做什么。我提供了我所有 inputs/rows/td 的 ID 以确保没有任何混淆,但这似乎不起作用。
代码
import { LitElement, html, css } from 'lit-element';
class TableList extends LitElement {
static get properties() {
return {
data: {
type: Array
},
primaryKey: {
type: String
},
defaultSortKey: {
type: String
}
};
}
set data(value) {
let oldValue = this._data;
this._data = [ ... value];
this.sortByHeader();
this.requestUpdate('data', oldValue);
}
get data() {
return this._data;
}
async edit(entry, key, event) {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('saved');
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('error');
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.add('saving');
if (entry[key].type === "checkbox") {
entry[key].value = event.target.checked;
} else {
entry[key].value = event.target.value;
}
if (await update(entry)) {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('saving');
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.add('saved');
setTimeout(() => {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('saved');
}, 1000);
} else {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('saving');
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.add('error');
setTimeout(() => {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('error');
}, 5000);
}
}
sortByHeader(key) {
if (key === undefined) {
key = this.defaultSortKey;
}
let oldValue = this.data;
this._data = [ ... this.data.sort((a, b) => {
return a[this.defaultSortKey].value - b[this.defaultSortKey].value
|| a[key].value - b[key].value;
})];
this.requestUpdate('data', oldValue);
}
renderHeaders() {
let keys = Object.keys(this.data[0]);
return keys.map(key => html`
${this.data[0][key].visible ?
html`
<th id="${'header' + key}" @click="${() => this.sortByHeader(key)}">
${key}
</th>
`: ''
}
`)
}
renderRows() {
return this.data.map(entry => html`
<tr id="${'entry' + entry[this.primaryKey].value}">
${Object.keys(entry).map(key => html`
${entry[key].visible && !entry[key].editable ?
html`<td>${entry[key].value}</td>`
: ``
}
${entry[key].visible && entry[key].editable ?
html`<td id="${'td' + key + entry[this.primaryKey].value}">
<input
id="${'input' + key + entry[this.primaryKey].value}"
name="${'input' + key + entry[this.primaryKey].value}"
type="${entry[key].type}"
?checked="${entry[key].value}"
value="${entry[key].value}"
@change="${(event) => {
this.edit(entry, key, event)
}}"
/>
</td>`
: ``
}
`)}
</tr>
`)
}
render() {
return html`
<table id="table-list">
<thead>
<tr>
${this.renderHeaders()}
</tr>
</thead>
<tbody>
${this.renderRows()}
</tbody>
</table>
`;
}
static get styles() {
return css`
table {
width: 100%;
border-collapse: collapse;
font-family: Arial, Helvetica, sans-serif;
}
th {
padding-top: 12px;
padding-bottom: 12px;
text-align: center;
background-color: #4CAF50;
color: white;
}
tr {
text-align: right;
-moz-transition: all .2s ease-in;
-o-transition: all .2s ease-in;
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
background: white;
padding: 20px;
}
.disabled {
color: lightgrey;
}
.saving {
background: yellow;
}
.saved {
background: lightgreen;
}
.error {
background: red;
}
.sort:after {
content: ' ↓';
}
`;
}
}
export default TableList;
如果您在模板中使用带有 id 的数组,请使用 lit-html
的重复函数
从“lit-html/directives/repeat”导入{重复};
对于样式,请勿手动将 类 添加到 DOM。使用来自 lit-html
的 classMap
从“lit-html/directives/class-map”导入 {classMap};
我解决了您的复选框问题,请按照此操作link。
有关 lit-html 的更多信息,请参阅他们的 documentation。
我正在尝试根据 Lit 元素中的值对 HTML table 进行排序。但是,我 运行 遇到了我的组件的问题。这是我的概述 table;
问题
在此应用程序中,您需要能够对每个 table header 进行排序。但是,被视为 'done' 的项目需要移至 table 的底部。每当我将项目标记为已完成时,我的问题就会出现。在下面的示例中,我会将最重要的待办事项(任务:123)标记为已完成。预期的行为是待办事项被移动到 table 的底部并启用了它的复选框。不过目前还不是这个结果。
如您所见,任务为 123 的待办事项已移至底部。但是,任务 456 的待办事项也标记了它的复选框。这不是我们想要的行为,我不知道是什么原因造成的。您还可以看到颜色不正确(这是一些样式,向您显示正在保存已更改的待办事项,黄色 = 保存,绿色 = 保存,红色 = 错误)。
我尝试过的东西
因为我不知道究竟是什么导致了这个问题,所以我不知道我应该做什么。我提供了我所有 inputs/rows/td 的 ID 以确保没有任何混淆,但这似乎不起作用。
代码
import { LitElement, html, css } from 'lit-element';
class TableList extends LitElement {
static get properties() {
return {
data: {
type: Array
},
primaryKey: {
type: String
},
defaultSortKey: {
type: String
}
};
}
set data(value) {
let oldValue = this._data;
this._data = [ ... value];
this.sortByHeader();
this.requestUpdate('data', oldValue);
}
get data() {
return this._data;
}
async edit(entry, key, event) {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('saved');
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('error');
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.add('saving');
if (entry[key].type === "checkbox") {
entry[key].value = event.target.checked;
} else {
entry[key].value = event.target.value;
}
if (await update(entry)) {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('saving');
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.add('saved');
setTimeout(() => {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('saved');
}, 1000);
} else {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('saving');
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.add('error');
setTimeout(() => {
this.shadowRoot.getElementById('entry' + entry[this.primaryKey].value).classList.remove('error');
}, 5000);
}
}
sortByHeader(key) {
if (key === undefined) {
key = this.defaultSortKey;
}
let oldValue = this.data;
this._data = [ ... this.data.sort((a, b) => {
return a[this.defaultSortKey].value - b[this.defaultSortKey].value
|| a[key].value - b[key].value;
})];
this.requestUpdate('data', oldValue);
}
renderHeaders() {
let keys = Object.keys(this.data[0]);
return keys.map(key => html`
${this.data[0][key].visible ?
html`
<th id="${'header' + key}" @click="${() => this.sortByHeader(key)}">
${key}
</th>
`: ''
}
`)
}
renderRows() {
return this.data.map(entry => html`
<tr id="${'entry' + entry[this.primaryKey].value}">
${Object.keys(entry).map(key => html`
${entry[key].visible && !entry[key].editable ?
html`<td>${entry[key].value}</td>`
: ``
}
${entry[key].visible && entry[key].editable ?
html`<td id="${'td' + key + entry[this.primaryKey].value}">
<input
id="${'input' + key + entry[this.primaryKey].value}"
name="${'input' + key + entry[this.primaryKey].value}"
type="${entry[key].type}"
?checked="${entry[key].value}"
value="${entry[key].value}"
@change="${(event) => {
this.edit(entry, key, event)
}}"
/>
</td>`
: ``
}
`)}
</tr>
`)
}
render() {
return html`
<table id="table-list">
<thead>
<tr>
${this.renderHeaders()}
</tr>
</thead>
<tbody>
${this.renderRows()}
</tbody>
</table>
`;
}
static get styles() {
return css`
table {
width: 100%;
border-collapse: collapse;
font-family: Arial, Helvetica, sans-serif;
}
th {
padding-top: 12px;
padding-bottom: 12px;
text-align: center;
background-color: #4CAF50;
color: white;
}
tr {
text-align: right;
-moz-transition: all .2s ease-in;
-o-transition: all .2s ease-in;
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
background: white;
padding: 20px;
}
.disabled {
color: lightgrey;
}
.saving {
background: yellow;
}
.saved {
background: lightgreen;
}
.error {
background: red;
}
.sort:after {
content: ' ↓';
}
`;
}
}
export default TableList;
如果您在模板中使用带有 id 的数组,请使用 lit-html
的重复函数从“lit-html/directives/repeat”导入{重复};
对于样式,请勿手动将 类 添加到 DOM。使用来自 lit-html
的 classMap从“lit-html/directives/class-map”导入 {classMap};
我解决了您的复选框问题,请按照此操作link。
有关 lit-html 的更多信息,请参阅他们的 documentation。