#javascript #sorting #checkbox #styling #lit-element
#javascript #сортировка #флажок #стиль #lit-элемент
Вопрос:
Я пытаюсь отсортировать таблицу HTML на основе ее значений в моем элементе Lit. Однако я столкнулся с проблемой с моим компонентом. Вот обзор моей таблицы;
Проблема
В этом приложении вам нужно иметь возможность сортировать по каждому заголовку таблицы. Однако элементы, которые считаются «выполненными», должны быть перемещены в нижнюю часть таблицы. Моя проблема возникает всякий раз, когда я отмечаю элемент как выполненный. В следующем примере я отмечу верхнюю задачу (задача: 123) как выполненную. Ожидаемое поведение заключается в том, что задача перемещается в нижнюю часть таблицы с включенным флажком. Однако это не то, что является результатом на данный момент.
Как вы можете видеть, элемент todo с задачей 123 перемещается в низ. Однако задача с задачей 456 также помечается флажком. Это нежелательное поведение, и я не знаю, что его вызывает. Вы также можете видеть, что цвета неверны (это некоторый стиль, чтобы показать вам, что измененное задание сохраняется, желтый = сохранение, зеленый = сохранено и красный = ошибка).
Вещи, которые я пробовал
Поскольку я не знаю, что именно вызывает эту проблему, я не знаю, что мне делать. Я дал все свои идентификаторы inputs / rows / td, чтобы убедиться, что ничего не перепутано, но, похоже, это не работает.
Код
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 amp;amp; !entry[key].editable ?
html`<td>${entry[key].value}</td>`
: ``
}
${entry[key].visible amp;amp; 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;
Комментарии:
1. Вам не нужно создавать свои собственные методы get / set для
data
. Это сделано для вас, посколькуdata
это свойство. Вам нужно искать измененияdata
вupdated(changedProperties)
методе LitElement.2. @Thad Но я хочу упорядочить список, как только он будет установлен, поэтому мне нужно его перезаписать.
3. Возможно, это поможет вам с сортировкой таблицы по столбцам со значками в lit-элементах jsabarinath.wordpress.com/2021/03/12 /…
Ответ №1:
- Если вы используете массив с идентификатором в шаблоне, используйте функцию повтора lit-html
импортируйте { repeat } из «lit-html/directives/repeat»;
- Для стилизации не добавляйте классы в DOM вручную. Используйте classMap из lit-html
импортируйте { classMap } из «lit-html/directives/class-map»;
Я исправил вашу проблему с флажком, пожалуйста, перейдите по этой ссылке.
Для получения дополнительной информации о lit-html, пожалуйста, обратитесь к их документации.