class가 총 3개 필요하다. constructor로 title, author, isbn을 담은
Book
, 입력한 book input을 화면에 출력할UI
.UI
안에는 사용자의 입력을 받아 실행된느 함수들이 있다. display(), add(), delete(), showAlert(), clearFields(). 마지막으로Store
는 localStorage에 저장하고 가져오는 class로 get(), add(), remove()가 있다.
이벤트 리스너도 3개가 있는데 하나는
DOMContentLoaded
.UI
에 있는 display()를 가진다. 그리고 add 버튼을 눌렀을 때 발생하는 이벤트 리스너는UI
에 add(), showAlert(), clearFieldS()로UI
에 입력값을 출력하고Store
에 입력값을 저장한다. preventDefault()와 validation check도 해야한다!
마지막으로
UI
에 출력된 정보를 삭제하는 이벤트 리스너는UI
의 delete()와 showAlert()를Store
에서 remove()를 한다. 대략적인 개요 끝이다.
html, css 생략
todo하다가 머리 식힐 겸 포스팅을 한다. 리스트가 있고 클릭하면 각각 리스트에 담겨진 다른 투두, 그러니까 객체 안에 객체가 있는 투두 만드는데 머리가 쥐난다. 으 짜증나... 하지만 친절하고 간결한 북리스트를 만들면서 머리를 식히도록 해야지
빠르게 js
class Book {
constructor(title, author, isbn){
this.title = title;
this.author = author;
this.isbn = isbn
}
}
class UI{
static displayBooks(){}
static addBookToList(){}
}
class Store{
}
class 3개 만들고 Book
에 constructor로 title, author, isbn를 준다. Store
는 나중에 local storage랑 관련이 있으니 일단 UI
부터 시작하자.
class UI{
static displayBooks(){
const StoredBooks = [{
title: "one",
author: "me",
isbn: "123"
},
{
title: "tow",
author: "yoi",
isbn: "456"
}]
const books = StoredBooks
books.forEach(book => UI.addBookToList(book))
}
static addBookToList(book){
const list = document.querySelector("#book-list");
const row = document.createElement("div")
row.classList.add("table-row")
row.innerHTML = `
<div class="table-cell" id="book-title">${book.title}</div>
<div class="table-cell" id="book-author">${book.author}</div>
<div class="table-cell" id="book-isbn">${book.isbn}</div>
<div class="table-cell"><a href="#" class="btn delete">X</a></div>
`
list.appendChild(row)
}
}
document.querySelector("#book-form").addEventListener("submit", e => {
e.preventDefault();
const title = document.querySelector("#title").value
const author = document.querySelector("#author").value
const isbn = document.querySelector("#isbn").value
const book = new Book(title, author, title)
UI.addBookToList(book)
}
일단 UI
안 displayBooks()
에 더미 데이터를 만든다. StoredBooks 배열에는 각 객체들이 있고 books라는 변수로 다시 받아서 books에 forEach를 한다. 각 객체를 book으로 하고 addBookToList()에 book을 파라메터로 보낸다.
addBookToList
에서 객체의 정보들이 담길 곳을 만들어야 한다. list는 html에서 가져오고 row는 만든다. 만든 row에 class 추가하고 innerHtml로 templated 완성. list에 child로 추가하면 된다.
이제 사용자가 정보를 입력하고 add 버튼을 누르면 display에 넣으면 되는데 일단 form을 가져와서 각 title, author, isbn의 value를 구한다. 그리고 이 각각의 새로운 값을 담음 새로운 객체를 만드는 const book = new Book(title, author, title)
을 해준다.(아직 직관적으로 와닿지 않음 공부 더 필요)
그리고 UI.addBookToList(book)
를 해주면 display가 된다.
class UI{
static deleteBook(el) {
if (el.classList.contains("delete")) {
el.parentElement.parentElement.remove()
}
}
}
document.querySelector("#book-list").addEventListener("click", e => {
UI.deleteBook(e.target)
})
"X"버튼을 누르면 해당 row가 삭제된다. 일단 list 전체에 이벤트 리스너를 건다. 처음에 버튼에 했다가 한참 돌아갔다. 이유는 나중에 정리하고 그러고 e.target을 하면 클릭할 때마다 태그를 보여주는데 그 target을 파라메터로 delete함수에 주면 된다. delete button이 될 태그 class로 delete를 주었고 class가 delete인 것에만 반응하여 해당 row를 remove() 하면 된다.
이제 Store
에서 저장하고 꺼내올 차례.
class Store {
static getBooks() {
let books;
if (localStorage.getItem("books") === null) {
books = []
} else {
books = JSON.parse(localStorage.getItem("books"))
}
return books
}
static addBook(book) {
const books = Store.getBooks()
books.push(book)
localStorage.setItem("books", JSON.stringify(books))
}
static removeBook(isbn) {
const books = Store.getBooks()
books.forEach((book, index) => {
console.log(book)
if (book.isbn === isbn) {
books.splice(index, 1)
}
})
localStorage.setItem("books", JSON.stringify(books))
}
}
Store
클래스엔 3개의 함수가 있다. 먼저 getBooks()
에서 저장된 데이터를 가져온다. books라는 변수를 만들고 if 문으로 "books"라는 key가 없으면 books 배열은 비었고 있다면 parse해서 books를 가져온다. 그리고 return 값은 books
addBook()
에서 book를 파라메터로 받고 books를 다시 정의(?)한다. Store.getBooks()의 return값이 addbooks() 안에서 books다. 그리고 books에 book을 넣으면 된다. 다 넣었으면 "books"가 key로 stringify한 books 객체가 value로 setItem을 한다.
remove()
는 isbn(여기서 약간 id 역할)을 파라메터로 받고 books를 getbooks()에서 다시 정의한다. books에 forEach해서 저장된 book의 isbn과 타켓된 isbn이 같으면 전체 books 객체에서 index번째에 있는 객체를 하나 지운다. (좀 헷갈림) 이 과정이 다 끝나면 setItem으로 다시 저장하면 된다.
static displayBooks() {
const books = Store.getBooks();
books.forEach(book => UI.addBookToList(book))
}
더미 데이터를 지우고 books를 local storage에서 가져오게 하면 된다. 그리고 add 이벤트 리스너에 Store.addBook(book)
새로 입력된 값을 저장하게 하면 된다.
delete 버튼 이벤트 리스너에도
Store.removeBook(e.target.parentElement.previousElementSibling.textContent)
해줘서 지운다. 끝!