본문 바로가기

code-states

[code-states][we-win] 18~23일차 - SNS 클론코딩 (1)

5일간의 여정을 마무리한다

정말로 어려웠고 실패도 많았고, 마지막엔 99% 구간에서 막혀서 좌절감도 들었지만

'100C' 와 99.9999C' 는 차이가 없어도 분명히 다르다!,

온도를 비교해 보자면 0.0001 차이가 나겠다만, Boiling Point 냐 아니냐는 YES/NO 로 갈린다'

라는 마인드로 끝까지 해 본 결과 이뤄내서 이번 과제는 특히 기억에 많이 남았다

트위터와 비슷한 시스템을 구현해봤다

저번에는 HTML/CSS 만들 가지고 트위터의 wireframe 을 디자인 했다면

이번엔 본격적으로 DOM/JS 를 통해 그 안의 기능들을 설계하였다

이것을 해결하기 위해서 사용한 개념들이나, 코드 노하우들을 다 적고 싶지만

혹시 몰라 찾아올 독자들이 보기엔 너무 가독성이 떨어질 것 같아

아무래도

1. 기능에 대한 설명

2. 그 기능을 구현하기 위해 들어간 코드의 역할들에 대한 설명

의 방식으로 글을 전개해 나가려고 한다

글에 목적성이 생기니 가독성도 올라가겠다는 생각...

 

 

 

 

 


 

 

 

 

[ 구현한 기능 ]

-repo 에 들어있는 코드들을 보면서, 어떻게 그것들을 기반으로 해서 내가 추가로 기능을 구현할 지 생각해본다

  -data.js 파일에 있는, 객체가 담긴 배열인 DATA array 를 기반으로 트윗을 만들어준다

  -data.js 파일에 있는, 배열들의 랜덤 조합을 만들어 내서 object 를 return 하는 함수를 통해 트윗을 만들어준다

-구현 해야하는 기능들을 배운 것들을 통해 적절히 구현하는 방법을 생각해본다

  -닉네임과 트윗을 입력할 수 있게 input 창을 만든 뒤에, 그 입력 데이터와 실제 시간을 가지고 트윗을 만들어준다

  -그렇게 만들어진 트윗들의 닉네임을 클릭하면, 그 닉네임의 소유자가 쓴 트윗만 sort 해서 보여준다

일단 이런 기능들을 만들어야 했고, 그래서 만들었다

이젠 각 기능들을 구현하기 위한 방법과, 사용한 개념들을 정렬해보려고 한다

 

 

 


 

 

 

 

기능 1. data.js 파일에 있는, 객체가 담긴 배열인 DATA array 를 기반으로 트윗을 만들어준다

앞서 말한 [ repo 에 들어있는 코드들을 보면서, 어떻게 그것들을 기반으로 해서 내가 추가로 기능을 구현할 지 생각해본다 ]

 

var DATA = [
  { user: 'ingikim', message: 'Welcome to Code States #codestates', created_at: '2019-01-03 12:30:20' },
  { user: 'satya', message: 'this is test message #pair #programming', created_at: '2019-01-04 18:30:20' },
  { user: 'sundar', message: 'code now! #work #hard', created_at: '2019-01-05 07:30:20' },
  { user: 'steve', message: 'Stay hungry, and stay foolish', created_at: '2015-01-03 12:30:20' },
  { user: 'tim', message: 'education for real world', created_at: '2019-01-04 18:30:20' }
];

;

코드처럼 배열 안에 객체들이 담겨있다

밑의 코드들을 마저 살펴보고 '이건 어떤 것들을 위한 코드구나' 하고

간략하게 주석을 달았다

그리고 저 객체를 통해 구현해야 하는 요구사항, [ data.js 파일에 있는, 객체가 담긴 배열인 DATA array 를 기반으로 트윗을 만들어준다 ]

를 위해서는 기존의 repo 안의 코드가 아닌 내가 새로 코드를 만들어야 한다는 것을 알게 되었다

 

psuedo code by drawing

 

즉, object 를 받아서 makingTweet 라는 함수에 넘겨주고, tweet 을 return 받으면 되는 것이다

그런데 하나 더 고려할 만한 점이 있었다, repo 의 기 선언된 코드 중 random 하게 트윗을 만들어주는 함수가 선언이 되었다는 점이다

function generateNewTweet() {
  var tweet = {};
  tweet.user = randomUser[getRandomInt(0, randomUser.length)];
  tweet.message = randomMessage[getRandomInt(0, randomMessage.length)];
  tweet.created_at = new Date(); // 어떻게 하면 보기 좋은 형태로 나타낼 수 있을까요?
  //alert('it works');
  return tweet;
}

객체를 받아서 객체를 넘기는 구조이다

그러면 여기서 또 생각이 가능한 부분이 있다

바로 callback function 의 특성 + functional programming 이다

generateNewTweet 이라는 저 함수 자체를

나의 makingTweet 의 parameter 로 받아서 그대로 넘겨버리면 되는 것이다

그렇다면 return 값은, [ JS를 통한 DOM 제어의 결과물을 html code 로 넘겨주는 ] 그런 값이 되어야 할 것이고

자연스레 makingTweet() 이라는 함수는 자연스럽게 [ JS를 통한 DOM 제어의 결과물을 html code로 넘겨주는 ] 함수가 되면 편할 것이다

그 이유는 그렇게 만들어 놓으면 코드의 재사용이 가능하기 때문이다

이렇게 가지가 뻗어나가는 형식으로 psuedo code 를 작성하고 있었다

코드로 적어보자면, 다음과 같았다

//트윗을 담은 틀을 담을 틀을 HTML 단에서 미리 만들고, querySelector 로 잡아준 뒤 사용하기 용이하게 변수로 만들어주었다 
let commentBox = document.querySelector('#commentBox');

//comment 라는 parameter 를 obect type 이라고 상정하고 함수를 선언하였다 
function makeHtmlEl(comment) {

    //tweet 전체를 담을 수 있는 틀 
    let liElement = document.createElement("li");

    //tweet 의 각 항목을 담는 틀 - 이름 요소 
    let userElement = document.createElement("button");
    userElement.innerHTML = comment.user;
    userElement.classList.add("userId");
    liElement.appendChild(userElement);

    //tweet 의 각 항목을 담는 틀 - 메시지 요소
    let msgElement = document.createElement("div");
    msgElement.innerHTML = comment.message;
    msgElement.classList.add("msg");
    liElement.appendChild(msgElement);

    //tweet 의 각 항목을 담는 틀 - 작성시간 요소
    let timeElement = document.createElement("span");
    timeElement.innerHTML = comment.created_at;
    timeElement.classList.add("created_at");
    liElement.appendChild(timeElement);

    //해당 요소를 담은 liElement 를 return 한다 
    return liElement;
}

; }

방법은 간단하다

-트윗을 받아 줄 li tag 를 만들어 준다

    -parameter 로 받은 object 의 'user' key 에 대한 value 를 li element 에 넣는다

    -parameter 로 받은 object 의 'msg' key 에 대한 value 를 li element 에 넣는다

    -parameter 로 받은 object 의 'created_at' key 에 대한 value 를 li element 에 넣는다

 

-내용이 담긴 li tag 를 return 한다

그리고 이제 그 HTML tag 를 넘기기 위한 함수를 또 만들어 주었다

function printComment(comment) {
    commentBox.appendChild(makeHtmlEl(comment));
}

;

 

 

 

 


 

 

 

 

 

[ total logic ]

     1. makeHtmlEl 에 comment 로 인자를 받아

     2. return 된 HTML tag 요소 liElement 를

     3. 위의 code block 최상단에 선언된, 트윗을 담은 틀을 담을 틀을 지칭한 HTML tag 변수에

     4. appendChild method 를 통해 추가해준다

 

사실상 이렇게 일련의 과정들을 이런 식으로 함수를 통해 선언하면 거의 끝이 났다

이제 나머지 과정들은 해당 함수들을 변칙적으로 사용하는 식으로 해결할 수 있다

여기서 주로 사용한 기능 및 개념은 :

기능 : createElement, querySelect, appendChild, innerHTML, textContent

개념 : call-back function and functional programming

사용한 이유는 :

기능의 경우, 태그를 만들고, 태그를 선택하고, 태그에 접근하고, 태그 안의 값들을 수정해주고, 태그에 태그를 추가해주는

그런 과정들을 위해서 사용하였다

개념의 경우, 함수를 받아 값을 return 하고 그 return 한 값을 번거롭게 선언/할당해서 할 필요 없이 그냥 call-back function 을 또 다른 함수의 parameter 로 집어넣어 깔끔하게 마무리하고 싶었기 때문에 사용하였다

 

 

 

 


 

 

 

 

다 쓰려고 했는데 도저히 너무 피곤해서 여력이 안 난다

나눠서 써야겠다...