Как правильно сохранять TODO list в LocalStorage?
Нужен совет как правильно сохранить список дел в LocalStorage. У меня есть масив, при добавлении нового дела, буду записывать его innerHTML и свойство check, в объект, потом этом объект пушить в масив. В результате получиться масив с объектами (делами). Который я уже спокойно буду кидать в LocalStorage. Но у меня проблема, при удалении дела, нужно удалять и его объект в масиве, и я не очень понимаю как это реализовать. Может есть какие-то другие варианты. Заранее благодарю! P.s. как вариант в LS можно сохранить целый container с делами. К примеру:
`localStorage.setItem("todos", container.innerHTML);`
Насколько это уместно?
Ответы (1 шт):
localStorage в песке отключен, поэтому для полного тестирования можно посетить JSFIDDLE
Не знаю насколько качественно и понятно, но делал в первый раз подобное.
Сначала думал будет не тривиальная и довольно простая задача, но потом углубился в Proxy и небольшое взаимодействие и кода так прибавилось.
Здесь есть один важный аспект - это Proxy.
Я его использовал только для того, чтобы следить за состоянием массива и проверять, не был ли он изменен.
После чего я запускал рендер и сохранял изменения.
Так же добавил смену состояния через чекбокс, удаление и добавление с помощью prompt.
Ответ оставляю общим, мне кажется я там перебрал с кодом и можно было сделать легче но я не знаю как (или просто лень).
(изначально все было на функциях и я перенес на классы, ибо обилие функций кровоточило глаза)
class Todo {
constructor() {
this.list = document.querySelector('ul');
const proxyHandle = {
set: (target, property, value) =>
this.proxySetHandle(target, property, value),
};
this.tasks = this.getTasks();
this.proxyTasks = new Proxy(this.tasks, proxyHandle);
this.renderTask();
const button = document.querySelector('button');
button.onclick = () => this.createTask();
}
taskSchema(status, name) {
const wrapper = document.createElement('li');
wrapper.innerHTML = (`
<input type="checkbox" ${status ? 'checked' : null}>
<span>${name}</span>
<i>x</i>
`);
return wrapper;
}
taskChangeStatus(index, status) {}
getTasks() {
return localStorage.getItem('tasks')
? JSON.parse(localStorage.getItem('tasks'))
: []
}
saveTasks() {
localStorage.setItem('tasks', JSON.stringify(this.tasks));
}
createTask() {
const name = prompt('Введите название задания');
if (name.length <= 0 || name.length > 100) return;
this.proxyTasks.push({
status: false,
name
});
}
changeTaskStatus(index, status) {
this.proxyTasks[index].status = status;
this.saveTasks();
}
removeTask(index) {
this.proxyTasks.splice(index, 1);
}
renderTask() {
this.list.innerHTML = '';
this.tasks.forEach(task => {
const schema = this.taskSchema(
task.status,
task.name
);
this.list.appendChild(schema);
});
const tasks = this.list.querySelectorAll('li');
tasks.forEach((task, index) => {
const status = task.querySelector('input');
const remove = task.querySelector('i');
status.onchange = (e) =>
this.changeTaskStatus(index, e.target.checked);
remove.onclick = () => this.removeTask(index);
});
}
proxySetHandle(target, property, value) {
target[property] = value;
this.saveTasks();
this.renderTask();
return true;
}
}
new Todo();
ul {
list-style-type: none;
}
ul li input:checked + span {
text-decoration: line-through;
}
ul li i {
color: red;
}
<button>Добавить задание</button>
<ul></ul>