-
-
Save youliangdao/3ec60ef2015d86e769c1dffcc93126bd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class View { | |
/** | |
* TODOの配列からUIを生成する関数 | |
* @param {Todo[]} todos | |
*/ | |
render(todos) { | |
const todosEl = document.getElementById("todos"); | |
todosEl.innerHTML = ""; | |
const fragment = document.createDocumentFragment(); | |
todos.forEach((todo) => { | |
const todoEl = this._createTodoElement(todo); | |
fragment.appendChild(todoEl); | |
}); | |
todosEl.appendChild(fragment); | |
} | |
/** | |
* TODO要素を作る | |
* @param {id: number, task: string} todo | |
* @returns todoのHTML要素 | |
*/ | |
_createTodoElement(todo) { | |
const { id, title, checked } = todo; | |
const todoEl = document.createElement("li"); | |
todoEl.id = `todo-${id}`; | |
const checkBoxEl = document.createElement("input"); | |
todoEl.appendChild(checkBoxEl); | |
const labelEl = document.createElement("label"); | |
labelEl.innerText = title; | |
checkBoxEl.type = "checkbox"; | |
checkBoxEl.id = `checkbox-${todo.id}`; | |
checkBoxEl.checked = checked; | |
todoEl.appendChild(labelEl); | |
if (checked) { | |
todoEl.className = `checked`; | |
} else { | |
todoEl.className = ""; | |
} | |
const buttonEl = document.createElement("button"); | |
buttonEl.id = `button-${id}`; | |
buttonEl.innerText = "削除"; | |
todoEl.appendChild(buttonEl); | |
return todoEl; | |
} | |
} | |
const view = new View(); | |
class Controller { | |
setup() { | |
this.handleSubmitForm(); | |
} | |
flash(todos) { | |
view.render(todos); | |
// イベントハンドラの付け直し | |
todos.forEach((todo) => { | |
const id = todo.id; | |
this.handleCheckTask(id); | |
this.handleClickDeleteTask(id); | |
}); | |
} | |
/** | |
* タスク送信時にTODO追加とUI反映をする | |
*/ | |
handleSubmitForm() { | |
window.addEventListener("load", () => { | |
const formEl = document.getElementById("task-send-form"); | |
formEl.addEventListener("ajax:success", (ev) => { | |
this.flash(ev.detail[0]); | |
}); | |
}); | |
} | |
/** | |
* 指定したcheckboxの状態変化に応じてTODO更新とUI反映をする | |
* @param {number} id TODOのid | |
*/ | |
handleCheckTask(id) { | |
const checkBoxEl = document.getElementById(`checkbox-${id}`); | |
checkBoxEl.addEventListener("change", (e) => { | |
const params = { | |
task: { | |
checked: e.target.checked, | |
}, | |
}; | |
fetch(`http://localhost:3000/tasks/${id}`, { | |
method: "PATCH", | |
headers: { | |
"X-CSRF-Token": Rails.csrfToken(), | |
"content-type": "application/json", | |
}, | |
body: JSON.stringify(params), | |
}) | |
.then((res) => { | |
return res.json(); | |
}) | |
.then((json) => { | |
this.flash(json); | |
}); | |
}); | |
} | |
/** | |
* 指定したTODO削除とUI反映をする | |
* @param {*} id TODOのid | |
*/ | |
handleClickDeleteTask(id) { | |
const buttonEl = document.getElementById(`button-${id}`); | |
buttonEl.addEventListener("click", () => { | |
fetch(`http://localhost:3000/tasks/${id}`, { | |
method: "DELETE", | |
headers: { | |
"X-CSRF-Token": Rails.csrfToken(), | |
"content-type": "application/json", | |
}, | |
}) | |
.then((res) => { | |
return res.json(); | |
}) | |
.then((json) => { | |
this.flash(json); | |
}); | |
}); | |
} | |
} | |
const formController = new Controller(); | |
formController.setup(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment