Разрешить пользователям изменять порядок нескольких объектов вместе
Мне нужна концепция помощи. У меня есть приложение с несколькими часами, датой и сообщением, и пользователь должен иметь возможность изменять порядок этих элементов любым способом.
Для часов, они могут добавить любое количество часов, включая отсутствие часов. Для этого я собираю массив часов. И тогда у меня есть один объект Date, который отображается и один объект сообщения.
Ниже приведен базовый пример настроек, которые у меня есть для каждого из них, и я могу добавить к этому, если необходимо, чтобы эта работа работала:
clocks: [
{
clockLabel: 'My clock',
...etc...
},
{
clockLabel: 'My second clock',
...etc...
}
],
theDate: [
enabled: true,
showYear: true,
...etc...
],
customMessage: [
enabled: true,
text: 'My custom message',
...etc...
]
Мне нужно выяснить способ, которым все эти элементы могут быть переставлены друг с другом так, чтобы было возможно иметь, например, 2 часа, затем дату, затем другие часы и затем сообщение.
Идея заключается в том, что в настройках пользователь может щелкнуть стрелку вверх или вниз для каждого элемента, чтобы переместить его вверх или вниз в списке всех элементов.
Я думал о том, чтобы иметь отдельный массив, в котором я мог бы отслеживать каждый элемент и переупорядочивать этот массив, но для этого я думаю, что мне нужно будет добавить идентификатор для каждого тактового генератора, чтобы привязать его к правильным часам в массиве сортировки, и Мне нужно удалить его из этого массива при удалении часов, но я не уверен, что это будет моим лучшим вариантом.
Для фактического отображения на странице я планировал использовать свойство CSS order с flexbox, чтобы отображать их в порядке, определяемом пользователем.
РЕДАКТИРОВАТЬ: Следует также отметить, что мне нужно иметь возможность сохранить заказ где-то, чтобы в следующий раз приложение загружалось, оно возвращается к порядку, установленному пользователем.
2 ответа
Было бы лучше, если бы вы могли представить position
свойство в каждом объекте, так что вам не нужно управлять новым массивом, чтобы узнать о позиции текущего объекта
Ниже я создал showPositionedResults
метод, чтобы вернуть отсортированный массив position
а также changePosition
метод для изменения положения элемента +- 1
когда пользователь нажимает на стрелку вверх и вниз.
let clocks = [
{
clockLabel: 'My clock',
position: 1
},
{
clockLabel: 'My second clock',
position: 2
}
],
theDate = [
{
enabled: true,
showYear: true,
position: 3
}
],
customMessage = [
{
enabled: true,
text: 'My custom message',
position: 4
}
]
let combinedResult = [...clocks, ...theDate, ...customMessage]
let originalCopy = JSON.parse(JSON.stringify(combinedResult))
// show sorted results by position
function showPositionedResults() {
return combinedResult.sort((a,b) => a.position - b.position)
}
console.log(showPositionedResults())
// change position by +- 1
function changePosition(position, up) {
let el = combinedResult.find(d => d.position == position)
if(up) {
combinedResult.find(d => d.position == position-1).position += 1
el.position -= 1
} else {
combinedResult.find(d => d.position == position+1).position -= 1
el.position += 1
}
}
// increase position 4 to 3
changePosition(4, true)
console.log(showPositionedResults())
// decrease position 1 to 2
changePosition(1, false)
console.log(showPositionedResults())
// original copy
console.log(originalCopy)
Допустим, начальная позиция элементов поддерживается в отдельном массиве с помощью индекса элементов:
let position = [0, 1, 2, 3];
Теперь, когда пользователь нажимает стрелку вверх на третьем элементе (index == 2
), вы знаете, что вам нужно сдвинуть третий элемент в массиве позиций на одну позицию вверх. (Вы можете определить, чья стрелка вверх была нажата, на основе индекса отображаемого элемента на экране, а не напрямую запрашивая его из ITEMS
массив. Это гарантирует, что вам не нужно отдельное поле ID.)
position = [0, 2, 1, 3];
Таким образом, всякий раз, когда нажимается второй элемент на экране, вы знаете, что вам нужно сдвинуть position
второй массив (index == 1
) элемент вверх / вниз.
Разве это не сработает для вас?