Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Советы по todo (https://javascript.ru/forum/dom-window/74824-sovety-po-todo.html)

villiwalla 10.08.2018 10:48

Советы по todo
 
Вложений: 1
Надеюсь, веткой не промазал.
Дабы лучше разобраться в JS, решил начать с примитивов. Первым что решил сделать это TODO. Вроде реализовать туду мне удалось, конечно наверняка собрав все самые детские грабли. Хотел бы получить комментарии с указанием на те самые грабли и возможно какие либо полезные советы, что бы держать вектор развития. Спасибо.

Линк

Вопросы:
1. Каким образом можно лучше организовать подписку элементов на события?
2. Почему в 80 строке if(row.classList.contains(elemClass)), в консоль пишет что у classList нету метода contains? (см.вложение) Хотя он работает как надо.
3. Чем заменить forEach в findById? Подойдёт ли map или filter, но тогда придётся перезаписывать let todos, плохо это или хорошо?

Nexus 10.08.2018 11:12

Цитата:

Сообщение от villiwalla
Почему в 80 строке if(row.classList.contains(elemClass)), в консоль пишет что у classList нету метода contains?

В какой-то ситуации у вашего "row" нет свойства "classList", а у null нет метода "contains".

Цитата:

Сообщение от villiwalla
3. Чем заменить forEach в findById? Подойдёт ли map или filter, но тогда придётся перезаписывать let todos, плохо это или хорошо?

Почему не создать дополнительный объект, в котором список задач будет индексированным? Тогда от перебора в этой функции можно вообще отказаться, все сведется к проверке наличия значения в индексном объекте и возвращению оного либо выбрасыванию ошибки.

рони 10.08.2018 11:12

villiwalla,
Цитата:

Сообщение от villiwalla
2. Почему в 80 строке if(row.classList.contains(elemClass)), в консоль пишет что у classList нету метода contains?

строка 203 или лишняя или не доделана(получается row, это event, а у event нет classList)

j0hnik 10.08.2018 11:15

Цитата:

Сообщение от villiwalla
1. Каким образом можно лучше организовать подписку элементов на события?

addEventListener

Dilettante_Pro 10.08.2018 11:22

villiwalla,
elem.innerText = `(${qty})`; - Не во всех браузерах работает
лучше elem.innerText = '('+qty+')';

Если id в todos упорядоченный и без пропусков, то
let todos = [
    {id: 1, status: false, text: 'Herb'},
    {id: 2, status: false, text: 'Tea'},
    {id: 3, status: false, text: 'Potato'},
    {id: 4, status: true, text: 'Meat'},
    {id: 5, status: false, text: 'Coal'},
    {id: 6, status: true, text: 'Beer'},
    {id: 7, status: true, text: 'Water'},
];
 id = "6";
 // todos.forEach((item, i) => {
 //       if(item.id === parseInt(id)) {
 //           result = {index: i, todo: item};
 //       }
 //   });
     let result = {index: id, todo: todos[id-1]} ;
alert(JSON.stringify(result));

villiwalla 10.08.2018 11:48

Цитата:

Сообщение от рони (Сообщение 492298)
villiwalla,

строка 203 или лишняя или не доделана(получается row, это event, а у event нет classList)

Точно, задублировал, и так в rowEvent ловлю клик

villiwalla 10.08.2018 12:06

Цитата:

Сообщение от Dilettante_Pro (Сообщение 492300)
villiwalla,
elem.innerText = `(${qty})`; - Не во всех браузерах работает
лучше elem.innerText = '('+qty+')';

Если id в todos упорядоченный и без пропусков, то
let todos = [
    {id: 1, status: false, text: 'Herb'},
    {id: 2, status: false, text: 'Tea'},
    {id: 3, status: false, text: 'Potato'},
    {id: 4, status: true, text: 'Meat'},
    {id: 5, status: false, text: 'Coal'},
    {id: 6, status: true, text: 'Beer'},
    {id: 7, status: true, text: 'Water'},
];
 id = "6";
 // todos.forEach((item, i) => {
 //       if(item.id === parseInt(id)) {
 //           result = {index: i, todo: item};
 //       }
 //   });
     let result = {index: id, todo: todos[id-1]} ;
alert(JSON.stringify(result));

Кроссбраузерность сейчас на последнем моменте, понятно что в прод должно уходить через бабел или тянуть полифилы.

todos.splice(todo.index, 1);

При удалении может вырезать середину.
При добавлении возрастает:
let id = todos[count(todos) - 1].id + 1;
        let todo = {
            id: id,
            status: false,
            text: text
        };


Цитата:

Сообщение от j0hnik (Сообщение 492299)
addEventListener

Это конечно понятно. Но на вопрос не отвечает. Наверное вы его не так поняли. Я о том как разбросаны коллбэки событий, например rowEvent для трёх элементов, отдельно для создания add. Каким образом можно организовать подписку слушателей события на всех элементах управления, более кучно?

Malleys 10.08.2018 13:08

У вас методы и переменные относящиеся к списку дел являются глобальными, что неожиданно сильно всё усложнит, если вдруг вы захотите, чтобы у вас был ещё один список.

Например, абстрактный тип данных «список дел» может быть оформлен в виде класса, и тогда все списки дел в программе будут являться объектами — экземплярами класса «список дел».

Вызвав new ToDoApp вы получаете ссылку на объект, в котором всё относится к одному определённому списку дел.

<body><script>

//описание класса «список дел»
class ToDoApp {
	constructor(todos) {
		this.todos = todos;
		
		//здесь возможно создать нужные элементы
		this.element = document.createElement("div");
		this.element.classList.add("todo");
		this.activeInput = null; // и т. д.
		
		this.render();
		
		// добавление событии
		this.element.addEventListener("keypress", this.rowEvent.bind(this));
		this.element.addEventListener("click", this.rowEvent.bind(this));
		
		// добавление в DOM приложения
		document.body.appendChild(this.element);
	}
	
	count() {}
	findById() {}
	rowEvent() {}
	closeActiveInput() {}
	createRow() {}
	
	add() {}
	remove() {}
	edit() {}
	render() {
		// для примера вывод текста задач, здесь всё очень приблизительно для примера,
		// но вы можете заполнить своим кодом из примера выше
		this.element.textContent = this.todos.map(task => task.text).join(", ");
	}
}

//	пример использования
var todoApp = new ToDoApp([
	{id: 1, status: false, text: 'Herb'},
    {id: 2, status: false, text: 'Tea'},
]);
	
var todoApp2 = new ToDoApp([
	{id: 1, status: false, text: 'CSS'},
    {id: 2, status: false, text: 'HTML'},
]);
	
</script>


Цитата:

Сообщение от villiwalla
Каким образом можно организовать подписку слушателей события на всех элементах управления, более кучно?

Это может быть сделано при создании нового экземпляра класса ToDoApp, когда вызывается функция constructor.


Цитата:

Сообщение от 9-ое издание спецификации ECMAScript, пункт 4.2.1
[...] часто бывает удобно определить абстракции похожие на класс [...] Встроенные объекты ECMAScript сами следуют такому шаблону. Начиная с ECMAScript 2015, язык ECMAScript включает определение синтаксиса классов, которое позволяет программистам кратко определять объекты, которые соответствуют тому же шаблону абстракции похожей на класс, который используется встроенными объектами.


villiwalla 10.08.2018 16:33

Malleys,
Спасибо, думал что сделаю как класс следующим этапом, но после того как через прототипы.


Часовой пояс GMT +3, время: 15:08.