-
Notifications
You must be signed in to change notification settings - Fork 118
[10기 soonysoo] TodoList with Ajax #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: soonysoo
Are you sure you want to change the base?
Changes from all commits
8b5d289
790eb72
65d1d74
cbdf87f
6d3315b
af540fb
7c14945
b34b937
af0181e
cd8a779
546269e
b3c81e8
1ceb526
c200c75
a91a154
abad275
75b7b66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { $, $$ } from "./util/util.js"; | ||
|
|
||
| import { Title } from "./component/Title.js" | ||
| import { TodoFilter } from "./component/TodoFilter.js"; | ||
| import { TodoInput } from "./component/TodoInput.js"; | ||
| import { UserList } from "./component/UserList.js"; | ||
| import { TodoList } from "./component/TodoList.js"; | ||
| import { userAPI, todoAPI } from "./api/api.js"; | ||
|
|
||
| import UserState from "../store/userState.js"; | ||
| import FilterState from "../store/FilterState.js"; | ||
| import SelectedUserState from "../store/SelectedUserState.js"; | ||
| import CountState from "../store/countState.js"; | ||
|
|
||
| export default class App{ | ||
| constructor(){ | ||
| this.selectedUserState = new SelectedUserState; | ||
| this.userState = new UserState; | ||
| this.filterState = new FilterState; | ||
| this.init(); | ||
| } | ||
| async init(){ | ||
| //conponent | ||
| this.title = new Title(this.selectedUserState); | ||
| this.userList = new UserList(this.userState, this.selectedUserState); | ||
| //console.log(this.selectedUserState) | ||
| this.todoInput = new TodoInput(this.selectedUserState); | ||
| this.todoList = new TodoList(this.selectedUserState, this.filterState); | ||
| this.todoFilter = new TodoFilter(this.selectedUserState, this.filterState); | ||
| //subscribe | ||
|
|
||
| this.selectedUserState.subscribe(this.title); | ||
| this.selectedUserState.subscribe(this.userList); | ||
| this.selectedUserState.subscribe(this.todoFilter); | ||
| this.selectedUserState.subscribe(this.todoList); | ||
|
|
||
|
|
||
| this.userState.subscribe(this.userList); | ||
| //this.userState.subscribe(this.todoList); | ||
| //this.userState.subscribe(this.todoFilter); | ||
|
|
||
| // this.todoState.subscribe(this.todoList); | ||
| // this.todoState.subscribe(this.todoFilter); | ||
|
|
||
| this.filterState.subscribe(this.todoList); | ||
| this.filterState.subscribe(this.todoFilter); | ||
|
|
||
| //this.countState.subscribe(this.todoFilter); | ||
| //초기데이터 | ||
| const initData = await userAPI.getAllUser(); | ||
| this.userState.set(initData); | ||
| this.selectedUserState.set(initData[0]); | ||
|
|
||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import { HTTP_REQUEST } from "./util.js"; | ||
|
|
||
| const BASE_URL = 'https://js-todo-list-9ca3a.df.r.appspot.com/api/users'; | ||
|
|
||
|
|
||
| export const userAPI = { | ||
| async getAllUser(){ | ||
| return await fetch(BASE_URL).then(data => data.json()); | ||
| }, | ||
| async deleteUser(id){ | ||
| return await fetch(`${BASE_URL}/${id}`,HTTP_REQUEST.DELETE()); | ||
| }, | ||
| async addUser(data){ | ||
| return await fetch(`${BASE_URL}`,HTTP_REQUEST.POST(data)).then(data=>data.json()); | ||
| }, | ||
| async getUser(id){ | ||
| return await fetch(`${BASE_URL}/${id}`).then(data => data.json()); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| export const todoAPI = { | ||
| async getTodoItem(id){ | ||
| return await fetch(`${BASE_URL}/${id}/items`).then(data => data.json); | ||
| }, | ||
| async addTodoItem(id, item){ | ||
| return await fetch(`${BASE_URL}/${id}/items`, HTTP_REQUEST.POST(item)); | ||
| }, | ||
| async deleteAllTodoItem(id){ | ||
| return await fetch(`${BASE_URL}/${id}/items`,HTTP_REQUEST.DELETE()); | ||
| }, | ||
| async deleteTodoItem(userId, itemId){ | ||
| return await fetch(`${BASE_URL}/${userId}/items/${itemId}`,HTTP_REQUEST.DELETE()); | ||
| }, | ||
| async updateTodoItem(userId, itemId, newItem){ | ||
| return await fetch(`${BASE_URL}/${userId}/items/${itemId}`, HTTP_REQUEST.PUT(newItem)); | ||
| }, | ||
| async updateTodoPriority(userId, itemId, priority){ | ||
| return await fetch(`${BASE_URL}/${userId}/items/${itemId}/priority`, HTTP_REQUEST.PUT(priority)); | ||
| }, | ||
| async toggleTodoItem(userId, itemId){ | ||
| return await fetch(`${BASE_URL}/${userId}/items/${itemId}/toggle`, HTTP_REQUEST.PUT()) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| const HTTP_REQUEST ={ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 따로 유틸 파일로 분리하셔서 사용하기 편리해 보입니다! |
||
| POST(data){ | ||
| return { | ||
| method : "POST", | ||
| headers :{ | ||
| 'Content-Type' :'application/json' | ||
| }, | ||
| body: JSON.stringify(data) | ||
| } | ||
| }, | ||
| DELETE(){ | ||
| return { | ||
| method : "DELETE", | ||
|
|
||
| } | ||
| }, | ||
| PUT(data){ | ||
| return { | ||
| method : "PUT", | ||
| headers :{ | ||
| 'Content-Type' :'application/json' | ||
| }, | ||
| body:JSON.stringify(data) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export {HTTP_REQUEST}; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import Observer from "../core/observer.js"; | ||
| import { $ } from "../util/util.js"; | ||
|
|
||
| export class Title extends Observer{ | ||
| constructor(selectedUserIdState){ | ||
| super(); | ||
| this.state = selectedUserIdState; | ||
| } | ||
| template(){ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. template가 먼저 보이는거 좋아요:) |
||
| const name = this.state.get().name; | ||
| return ` | ||
| <span><strong>${name}</strong>'s Todo List</span> | ||
| ` | ||
| } | ||
| render(){ | ||
| const target = $("#user-title"); | ||
| target.innerHTML = this.template(); | ||
| } | ||
| update(){ | ||
| this.render(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| import Observer from "../core/observer.js"; | ||
| import { $, $$ } from "../util/util.js"; | ||
| import { FILTER } from "../constants/constants.js"; | ||
| import { todoAPI, userAPI } from "../api/api.js"; | ||
|
|
||
| export class TodoFilter extends Observer{ | ||
| constructor(selectedUserState, filterState){ | ||
| super(); | ||
| this.selectedUserState = selectedUserState; | ||
| this.filterState = filterState; | ||
| } | ||
| templete(){ | ||
| const filter = this.filterState.get(); | ||
| const todo = this.selectedUserState.get().todoList; | ||
| const count = this.counTotalTodo(filter, todo); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. coun 오타가 있습니다 |
||
| return ` | ||
| <span class="todo-count">총 <strong>${count}</strong> 개</span> | ||
| <ul class="filters"> | ||
| <li class="li-filter"> | ||
| <a href="#" class="all ${filter =="all"?"selected":""}">전체보기</a> | ||
| </li> | ||
| <li class="li-filter"> | ||
| <a href="#active" class="active ${filter =="active"?"selected":""}">해야할 일</a> | ||
| </li> | ||
| <li class="li-filter"> | ||
| <a href="#completed" class="completed ${filter =="completed"?"selected":""}">완료한 일</a> | ||
| </li> | ||
| </ul> | ||
| <button class="clear-completed">모두 삭제</button> | ||
|
|
||
| ` | ||
| } | ||
| render(){ | ||
| const target = $(".count-container"); | ||
| target.innerHTML = this.templete(); | ||
| this.mounted(); | ||
| } | ||
| mounted(){ | ||
| const filterBtn = $$('.li-filter'); | ||
| filterBtn.forEach(btn => btn.addEventListener('click',this.onFilterChange.bind(this))); | ||
|
|
||
| const deleteAllBtn = $('.clear-completed'); | ||
| deleteAllBtn.addEventListener('click', this.onDeleteAllTodo.bind(this)); | ||
| } | ||
| update(){ | ||
| this.render(); | ||
| } | ||
| async onDeleteAllTodo(){ | ||
| const selectedId = this.selectedUserState.get()._id; | ||
| const response = await todoAPI.deleteAllTodoItem(selectedId); | ||
| if(response.ok){ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 응답코드 체크는 만드신 api파일에서 확인해주시면 더 간결해 보일 것 같습니다!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 넵~ 수정해야겠네요 ㅎㅎ |
||
| const data = await userAPI.getUser(selectedId); | ||
| this.selectedUserState.set(data); | ||
| } | ||
| } | ||
| onFilterChange(e){ | ||
| const mode= e.target.className.replace('selected','').trim(); | ||
| this.filterState.set(mode); | ||
| } | ||
| counTotalTodo(filter, todo){ | ||
| if(filter ==FILTER.ALL){ | ||
| return todo.length; | ||
| } | ||
|
|
||
| if(filter == FILTER.ACTIVE){ | ||
| return todo.filter(item => !item.isCompleted).length | ||
| } | ||
| if(filter == FILTER.COMPLETED){ | ||
| return todo.filter(item => item.isCompleted).length | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| //import Observer from "../core/observer.js"; | ||
| import { $ } from "../util/util.js"; | ||
| import { userAPI, todoAPI } from "../api/api.js"; | ||
|
|
||
|
|
||
| export class TodoInput { | ||
| constructor(selectedUserState){ | ||
| this.selectedUserState = selectedUserState; | ||
| this.addEvent(); | ||
| } | ||
| addEvent(){ | ||
| const target = $(".new-todo"); | ||
| target.addEventListener('keyup', this.onAddTodo.bind(this)); | ||
| } | ||
| async onAddTodo(e){ | ||
| if(e.key==='Enter'){ | ||
| const value = e.target.value; | ||
| const id = this.selectedUserState.get()._id; | ||
| if(value.length <2 ){ | ||
| alert("콘텐츠의 길이는 최소 2글자이상이어야 합니다."); | ||
| return; | ||
| } | ||
| await todoAPI.addTodoItem(id, {"contents":value}); | ||
| const data = await userAPI.getUser(id); | ||
| this.selectedUserState.set(data); | ||
| e.target.value = ""; | ||
| } | ||
| } | ||
|
|
||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then-catch대신 async-await를 사용 하신 것 같습니다 !
then 사용 대신 변수에 담아서 반환하셔도 될 것 같아요 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그렇네요! async-await적용을 전체를 다 하지못했네요~
수정하겠습니당!