1: 디자인 패턴 정의 - 위키백과 2: 에리히 감마(Erich Gamma), 리차드 헬름(Richard Helm), 랄프 존슨(Ralph Johnsom), 존 블리시디스(John Vissides)를 말한다. 소프트웨어 개발 영역에서 디자인 패턴을 구체화하고 체계화한 사람들이다.
let data = [ { id: 1, type: '2', category: '2', date: '2021-06-20', content: '지훈님께서 아침에 트라이(Trie) 가사 검색 문제에 대한 힌트를 잘 알려주셔서 문제를 이해하고, 푸는데 정말 큰 도움이 되었다.', order: 1 }, { id: 23, type: '1', category: '1', date: '2021-06-23', content: '자두 캘린더 마우스이벤트', order: 2 } ... ] ``` 위와 같은 배열을 사용했다. ## 고려했던 다른 데이터 방식 ```javascript let data = [ { 2020:{ }, 2021:{ 6:{ 20:{ id: 1, type: '2', category: '2', content: '지훈님께서 아침에 트라이(Trie) 가사 검색 문제에 대한 힌트를 잘 알려주셔서 문제를 이해하고, 푸는데 정말 큰 도움이 되었다.', order: 1 } 23:{ id: 23, type: '1', category: '1', content: '자두 캘린더 마우스이벤트', order: 2 } } } } ]
달력이니 날짜를 기준으로 데이터를 관리하면 편할 거란 생각이 들어 위와 같은 데이터 관리 방식을 고민해봤었다. 하지만 이러면 데이터의 깊이가 너무 깊어지고 일저의 날짜가 바뀌면 옮기기도 어려워져 다른 방식을 택했다.
// 이동할 위치에 아무 일정도 없는 경우 if (!$lastElement) { $container.style['border-top'] = 'solid 5px gray'; $prevContainer = $container; return; }
// 이동할 위치에 현재 이동중인 자신의 일정이 있는데 // 그게 이동할 위치의 마지막이고 자신보다 위에 일정이 있는 경우 const $prevElement = draggable.previousElementSibling; if ($lastElement === draggable && $prevElement) { $prevElement.style['border-bottom'] = 'solid 5px gray'; $prevNextElement = $prevElement; return; }
// 이동할 위치에 현재 이동중인 자신의 일정만 있는 경우 if ($lastElement === draggable) { $container.style['border-top'] = 'solid 5px gray'; $prevContainer = $container; }
// 이동할 위치에 현재 이동중인 자신의 일정이 있는데 // 그게 이동할 위치의 마지막이 아니고 들어가려고 하는 위치는 마지막인 경우 if ($lastElement !== draggable) { $lastElement.style['border-bottom'] = 'solid 5px gray'; $prevNextElement = $lastElement; } }, mouseUpEvent() { draggable.classList.remove('dragging'); draggable.style.transform = 'none';
if ($prevNextElement) $prevNextElement.style.border = 'none'; if ($prevContainer) $prevContainer.style.border = 'none';
What forces layout / reflow 문서를 보면 Element APIs > Getting box metrics > elem.getBoundingClientRect() 가 있음을 볼 수 있다. 즉, 이 메서드를 호출할 때마다 브라우저는 요소의 크기와 위치값을 최신 정보로 가져오기 위해 문서의 일부 혹은 전체를 다시 그리는 리플로우(reflow) 현상이 발생한다. 이 메서드를 일정을 드래그할 때마다 호출하게 되면 성능에 문제를 줄 수 있다. 요소의 크기와 위치값이 캐시될 수 있지만, JADOO 프로젝트의 경우, 일정이 새로 생성, 삭제, 이동되면서 getBoundingClientRect() 메서드로 계산할 요소의 크기와 위치값이 계속 변동되어 새로 계산될 확률이 높으므로 사용하지 않았다. //(MutationObserver를 사용해 호출 수를 줄이는 방법도 있긴 하다.)
HTMLCollection 객체와 NodeList 객체를 배열로 변환해서 사용하는 이유를 기억하기 위해
결론
노드 객체의 상태 변경과 상관없이 안전하게 DOM 컬렉션을 사용하려면 HTMLCollection 객체나 NodeList 객체 모두 배열로 변환하여 사용하는 것을 권장한다. 둘 모두 유사 배열 객체이면서 이터러블이므로 스프레드 문법이나 Array.from 메서드를 사용하면 간단히 배열로 변환할 수 있다.
app.use() 안의 함수들은 모두 middleware(미들웨어)이며 request(요청)가 올때마다 이 middleware가 실행된 후, Client에 response(응답)한다.
express.static(root, [options])
express.static()은 Express의 유일한 기본 제공 middleware(미들웨어) 함수이다. 이 함수는 serve-static을 기반으로 하며, Express application의 정적 자산을 제공한다.
root 인수는 정적 자산의 제공을 시작하는 위치인 root directory를 설정한다.
app.use(express.static(‘public’));
app(=Server)에 request(요청)이 올 때마다 express.static(‘public’)을 실행하여 root directory를 public으로 설정한다.
1
app.use(express.json()); // for parsing application/json
request(요청)에 넘어오는 payload(페이로드)를 json 형식으로 pharsing(파싱)한다.
1 2 3 4
// The app.listen() function is used to bind and listen the connections on the specified host and port. app.listen(PORT, () => { console.log(`Server is listening on http://localhost:${PORT}`); });
app.listen()
app.listen()은 지정된 host 및 port의 connection을 bind(연결)하고 listen(수신 대기)한다.
1 2 3 4 5 6
// Stored data on a server let todos = [ { id: 3, content: 'JavaScript', completed: false }, { id: 2, content: 'CSS', completed: true }, { id: 1, content: 'HTML', completed: false } ];
서버에 저장된 데이터를 의미한다.
-1. FetchTodos
1 2 3 4
// The app.get() function define a route handler for GET requests to a given URL. app.get('/todos', (req, res) => { res.send(todos); });
app.get(path, handler)
app.get(path, handler)는 주어진 URL로부터 GET request가 올 때 실행될 route handler를 정의한다.