과제 Rule
다음과 같이 과제가 주어졌고, 내가 직접 구현한 것만 체크하였다.
Bare Minimum Requirement
- 디스커션 나열 기능
- ☑️
script.js
를 수정하여agoraStatesDiscussions
배열의 데이터를 나열할 수 있게 구현합니다.- ☑️ CSS
- ☑️ 디스커션 추가 기능
- ☑️
script.js
를 수정하여 디스커션 추가 기능을 구현합니다.- ☑️
section.form__container
요소에 새로운 아고라 스테이츠 질문을 추가할 수 있는 입력 폼을 제작합니다. 형식은 자유입니다.- ☑️ 아이디, 본문을 입력하고 버튼을 누르면 실제 화면에 디스커션이 추가되어야 합니다.
- ☑️
agoraStatesDiscussions
배열에 추가한 데이터가 실제 쌓여야 합니다.- ☑️ Github Page 배포
- ☑️ Github Page 배포 기능을 이용하여 누구나 볼 수 있게 배포합니다.
- ☑️ 코드스테이츠 fe-sprint-my-agora-states 리포지토리로 Pull Request
- ☑️ 나만의 아고라 스테이츠를 코드스테이츠 깃허브에 Pull request합니다.
- ☑️ 주어진 Pull request 형식에 따라주세요.
Advanced Challenge
- ☑️ 현지 시간 적용
- ☑️ 샘플 시간을 잘 변형하여, 현지 시간에 맞게 표현합니다. (ex. 오전 10:02:17)
- 페이지네이션 기능
- ☑️ 페이지네이션에 대해서 스스로 학습합니다.
- 한 페이지에 10개씩 디스커션이 보여야 합니다.
- 다음 페이지로 넘어갈 수 있어야 합니다.
- 이전 페이지로 돌아올 수 있어야 합니다.
- 다음 페이지가 없거나, 이전 페이지가 없는 경우 페이지를 유지해야 합니다.
- ☑️ 디스커션 유지 기능
- ☑️ LocalStorage에 대해서 스스로 학습하고, 새롭게 추가하는 Discussion이 페이지를 새로고침해도 유지되도록 제작합니다.
👩🏻💻 CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// convertToDiscussion은 아고라 스테이츠 데이터를 DOM으로 바꿔준다.
const convertToDiscussion = (obj) => {
const li = document.createElement("li"); // li 요소 생성
li.className = "discussion__container"; // 클래스 이름 지정
const avatarWrapper = document.createElement("div");
avatarWrapper.className = "discussion__avatar--wrapper";
const discussionContent = document.createElement("div");
discussionContent.className = "discussion__content";
const discussionAnswered = document.createElement("div");
discussionAnswered.className = "discussion__answered";
// Img
const avatarImg = document.createElement('img');
avatarImg.className = 'discussion__avatar--image';
avatarImg.src = obj.avatarUrl ? obj.avatarUrl : './webare.png'; // 이미지 경로가 없을 경우에는 기본 이미지로
avatarImg.alt = 'avatar of ' + obj.author;
avatarWrapper.append(avatarImg);
// Title
const discussionTitle = document.createElement('h4');
discussionTitle.className = 'discussion__title';
const discussionA = document.createElement('a');
discussionA.href = obj.url;
discussionA.textContent = obj.title;
discussionTitle.append(discussionA);
// 작성한 사람 정보
const discussionInform = document.createElement('div');
discussionInform.className = 'discussion__information';
discussionInform.textContent = `${obj.author} / ${new Date(obj.createdAt).toLocaleTimeString('ko-kr')}`;
discussionContent.append(discussionTitle, discussionInform);
// answer 확인
const discussionAnswer = document.createElement('p');
obj.answer !== null ? discussionAnswer.textContent = '♥' : discussionAnswer.textContent = '♡';
discussionAnswered.append(discussionAnswer);
li.append(avatarWrapper, discussionContent, discussionAnswered);
return li;
};
// agoraStatesDiscussions 배열의 모든 데이터를 화면에 렌더링하는 함수
const render = (element) => {
for (let i = 0; i < agoraStatesDiscussions.length; i += 1) {
element.append(convertToDiscussion(agoraStatesDiscussions[i]));
}
return;
};
// localStorage 함수
const renderlocalStorage = (element) => {
const objLocalData = JSON.parse(localStorage.getItem('agoraDatas'));
if (objLocalData) {
for (let i = 0; i < objLocalData.length; i++) {
element.prepend(convertToDiscussion(objLocalData[i]));
}
// renderPagination(); // 확인중
}
return;
}
// ul 요소에 agoraStatesDiscussions 배열의 모든 데이터를 화면에 렌더링한다.
const ul = document.querySelector("ul.discussions__container");
render(ul);
renderlocalStorage(ul);
// Form 데이터 삽입
const formInput = document.querySelector('.form');
const formNameInput = document.querySelector('#name');
const formTitleInput = document.querySelector('#title')
const formQuestionInput = document.querySelector('#story');
formInput.addEventListener('submit', (event) => {
event.preventDefault();
const newObj = {
id: "D_kwDOHOApLM4APjJim",
createdAt: new Date().toISOString(),
title: formTitleInput.value,
url: "https://github.com/codestates-seb/agora-states-fe/discussions/45",
author: formNameInput.value,
answer: null,
bodyHTML: formQuestionInput.value,
avatarUrl: null
}
window.localStorage.clear();
let objData = [];
if (localStorage.length > 0) {
let bjLocalData = JSON.parse(localStorage.getItem('agoraDatas'));
for (let i = 0; i < bjLocalData.length; i++) {
objData.push(bjLocalData[i]);
}
}
objData.push(newObj);
localStorage.setItem('agoraDatas', JSON.stringify(objData));
agoraStatesDiscussions.unshift(newObj);
ul.prepend(convertToDiscussion(newObj));
formInput.reset();
})
Feelings …
그 전까지는 주어진 틀 안에서 맞는지 틀렸는지 확인하는 식으로 수행하였는데, 이번에는 처음부터 내가 구현할려니까 너무 힘들었다 😭 구현하는 속도가 너무 느려서 기능을 전부 다 구현하지 못했지만.. 그래도 열심히 했다 ㅠㅠㅠ 시작하기 전부터 .. 헉 막막하다 이런생각도 들었지만 그래도 반 넘게 구현해서 다행이라고 생각한다..
[처음 배포한 나의 깃허브 프로젝트] https://sinetlsl.github.io/fe-sprint-my-agora-states/
Findings …
- Window.localStorage 에서 자주 사용하는 메서드는
setItem(key, value)
,getItem(key)
,removeItem(key)
,clear()
가 있다.- JSON.parse() : JSON 문자열 -> JavaScript 값으로 변환
- JSON.stringify() : JavaScript 값 -> JSON 문자열로 변환
- addEventListener에서 submit을 사용할 경우,
event.preventDefault()
를 적용해주면 브라우저 기본 동작인 새로고침이 되는 현상 방지한다.
Reference