JavaScript 마크다운, 템플릿 활용

2022. 2. 13. 17:22JavaScript/김민태의 프론트엔드 아카데미 1

 

▶ 지난 강의

3-1. Hacker News 클라이언트 앱

어플리케이션 직접 만들어보면서 입력 데이터를 가공하고 출력하는 프로그래밍이 어떻게 진행되는지 체험하는 것이 목적이고, CSS와 관련된 디자인적인 부분과 비동기화는 제외하고 실습한다.

 

3-2. 코드 12줄

네트워크 너머의 서버에서 데이터를 받아 Unordered-list로 가공하고, Parcel js로 실행시켜 데이터를 출력하는 프로그램을 직접 만들어본다. 

첫번째로는 XMLHttpRequest와 ajax, innerHTML

두번째로는 createElement(' li '), appendChild(ul) 을 기억하면 된다.

 

3-3. 두개의 화면 웹앱

특정 링크 클릭시 다른 창이나 화면 효과가 나타나도록 한다. AddEventListener를 기억하면 된다.

 

3-4. 문자열 활용 HTML

3-5. 라우터 화면 처리기 3-6. 페이징 구현하기 

 

▶ 이번 강의

3-7. 복잡한 UI 구현을 위한 준비작업-템플릿 

CSS 사용시 코드 양이 많아져도, 마크업이 복잡하지 않아 코드가 한눈에 이해되게 하려면 dom API 사용을 줄이고 배열 이용한 문자열 마크업 방식을 변화시켜야한다. replace ('템플릿', 대신 들어갈 내용); 을 통해 이미 만들어둔 템플릿에 넣을 내용을 대체할 대상으로 replace 기능 안에 넣는다. 

 

1. 코드

const container = document.getElementById('root');
const ajax = new XMLHttpRequest();
const content = document.creatElement('div');
const NEWS_URL = 'https://api.hnpwa.com/v0/news/1.json';
const CONTENT_URL = 'https://api.hnpwa.com/v0/item/@id.json';
const store = {
    currentPage : 1,
};
function getData(url){
    ajax.open('GET',url,false);
    ajax.send();

    return JSON.parse(ajax.response);
}
const ul = document.createElement('ul');

function newsFeed(){
    const newsFeed = getData(NEWS_URL);
    const newsList = [];
    //UI 작업 위해 필요한 템플릿으로 코드 정리
    //1. 템플릿 변수 생성하여 틀 만들기
    //2. li, a 대신에 newsfeed로 마크업, a태그들에는 # 다음에 page 구분위해 prev_page 등의 변수 사용 
    //3. tailwind 위해 class 를 container로 사용, margin은 m, padding은 p로 축약
    let template = '<div class = "cntainer mx-auto p-4>'+
        
        '    <h1>Hacker News 큰제목</>'+
        '    <ul>'+
        '        {{__news_feed__}}'+

        '    </ul>'+
        '    <div>'+
        '        <a href="#/page/{{__prev_page__}}">이전 페이지</a>'+
        '        <a href="#/page/{{__next_page__}}">이후 페이지</a>'+
        '    </div>'+
        '</div>';

    //템플릿 덕분에 필요 없어진 코드 1 newsList.push('<ul>');
    for(let i=(store.currentPage-1)*10;i<  store.currentPage*10; i++){
        newsList.push('<li>'+                
            '<a href="#/show/${newsFeed[i].id}">'+
            '    ${newsFeed[i].title} (${newsFeed[i].comments_count})'+
            '</a>'+
            '</li>');
    }

    template = template.replace ('{{__news_feed__}}', newsList.join(''));
    template = template.replace ('{{__prev_page__}}', store.currentPage > 1 ? store.currentPage-1:1);
    template = template.replace ('{{__next_page__}}', store.currentPage+1);
    
    //container.innerHTML =newsList.join();
    container.innerHTML = template;

}
function newsDetail(){
    const id = location.hash.substring(7);
    const newsContent = getData(CONTENT_URL.replace('@id',id))    
    container.innerHTML = '<h1>${newsContent.title}</h1>'+
       '<div>'+       
       '   <a href="#/page/${store.currentPage}">목록으로</a>'+
       '</div>   ';

}
function router(){
    const routePath = location.hash;
    if(routePath ===''){
        newsFeed();

    }else if(routePath.indexOf('#/page/')>=0){
        store.currentPage = Number(routePath.substr(7));
        newsFeed();
    }else{
        newsDetail();
    }   
}
window.addEventListener('hashchange',newsDetail);
router();

UI 작업을 들어가기 전, CSS 수정하더라도 코드의 양만 많아지고 구조 자체는 복잡해지지 않도록 템플릿을 이용해 코드를 더 간결하게 수정하는 작업이다.

 

상수 const와 다르게 변수 let으로 template 을 만들어두고, 코드에서 반복 등장하는 부분들을 template으로 대체한다. 본 코드에서는 ul태그 이후에 unorderd-list 목록을 만들기 위한 li 태그들을 markup한 상태에서 a태그와 ul 태그들을 합쳐 template으로 만들어놓았다.

 

 

2. 가져갈 것

1. 마크업 사용

a 태그에서 같은 #이라도 어떤 용도인지 구분하기 위해 {{__prev_page__}}를 활용해 마크업해둔다.

unordered lists를 만들기 위해 반복되는 li 코드와 a태그에 얽힌 링크들을 news_feed로 묶어둔다.

 

2. 템플릿 사용

코드의 복잡성을 줄여 CSS 수정이 용이하도록, 템플릿을 활용한다. 그냥 반복되는 부분을 전부 let template에 넣고 다른 코드에서 해당 부분이 나올때마다 template으로 대체하면 된다.

 

 

▶ 다음 강의

3-8. 댓글목록이 표시되는 아름다운 UI 만들기

3-9. 상태를 가져보자, 읽은 글 표시하기