Skip to content

Instantly share code, notes, and snippets.

@sergey-kras
Last active October 24, 2019 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sergey-kras/2365bc69bffc81ea1b84cef7c7dd5c5b to your computer and use it in GitHub Desktop.
Save sergey-kras/2365bc69bffc81ea1b84cef7c7dd5c5b to your computer and use it in GitHub Desktop.
todoVOVA.js
"use strict";
/** Класс State отвечает за общение между localStorage и DOM
* @initialState заполняет объект данными из localStorage или наоборот выгружает туда заготовку
* @reloadState Выдывается каждый раз при изменении чего либо в стейте, сдедом за собой
* вызывает обновление дома
* @addTask просто добавляет таску
* @addTask просто удаляет таску
* @this tasks временно хранит в себе задачи
* @this state отдает текущие задачи вовне
* */
class State {
tasks = [];
constructor() {
this.initialState();
}
get state() {
return this.tasks;
}
initialState = () => {
if(!localStorage.tasks) {
localStorage.tasks = JSON.stringify(this.tasks);
} else {
this.tasks = JSON.parse(localStorage.tasks);
}
};
reloadState = () => {
localStorage.tasks = JSON.stringify(this.tasks);
DOM.initialDOM(this.tasks);
};
addTask = ({text}) => {
const status = false;
const id = generateId();
this.tasks.push({text, status, id});
this.reloadState();
};
removeTask = id => {
const newState = this.tasks.filter(task => task.id !== id);
this.tasks = newState;
this.reloadState();
};
editTask = ({ id, text, status }) => {
const newState = this.tasks.map(task => {
if (task.id === id) {
return {
id,
text: text || task.text,
status: status
}
}
return task;
});
this.tasks = newState;
this.reloadState();
};
}
/** Класс DOMProvider отвечает за оптимизированного (в идеале, этого еще не сделано) общения с DOM
* @initialDOM берет данные из стейта и инициализирует дом
* @taskTemplate Просто html шаблон таски
* */
class DOMProvider {
container = $('#todoList');
constructor(state) {
this.initialDOM(state);
}
initialDOM = (state) => {
let initObject = '';
state.map((task, index) => {
initObject += this.taskTemplate(task, index);
});
this.container.html(initObject);
};
taskTemplate = ({ text, status, id }, index) => {
const completeMod = status ? '_complete' : '';
return (`<div class="task" data-id="${id}">
<input class="task__check" type="checkbox" class="complete" ${completeMod && 'checked'}>
<div class="task__number">${index}</div>
<div class="task__text ${completeMod}">
${text}
</div>
<button class="task__delete">Удалить</button>
<button class="task__edit">Редактировать</button>
</div>`);
}
}
/** Класс Eventer отвечает запуск прослушивания кликов и сообщения в State
* @startListners Запускает слушателей
* @listenForm Слушает все события в форме
* @listenRemove Слушает все события при клике на удаление
* */
class Eventer {
constructor() {
this.startListners();
}
startListners = () => {
this.listenForm();
this.listenRemove();
this.listenCheck();
};
listenForm = () => {
$("#formAdd").submit(e => {
e.preventDefault();
const input = $('#taskText');
const value = input.val();
input.val('');
STATE.addTask({ text: value });
});
};
listenRemove = () => {
$("#todoList").on('click', '.task__delete', e => {
const taskId = $(e.target).parent('.task').data('id');
STATE.removeTask(taskId);
});
};
listenCheck = () => {
$("#todoList").on('change', '.task__check', e => {
const id = $(e.target).parent('.task').data('id');
const status = $(e.target).prop('checked');
STATE.editTask({ status, id });
});
}
}
/**
* @generateId Вспомогательная функция для генерации id каждому таску
* */
function generateId() {
let rand = 1000000 - 0.5 + Math.random() * (9999999 - 1000000 + 1);
return Math.round(rand);
}
new Eventer();
const STATE = new State();
const DOM = new DOMProvider(STATE.state);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment