handlebar
대표적인 template 라이브러리
구글에 handlebar cdn을 검색하여 스크립트 태그 복사해오기
min은 mini file로 압축된 파일을 의미
min이 마지막에 붙은 것으로 복사해오기
https://cdnjs.com/libraries/handlebars.js
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"
integrity="sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg=="
crossorigin="anonymous"
referrerpolicy="no-referrer">
</script>
html에 다음과 같이 template 코드를 생성
<script type="myTemplate" id="listTemplate">
<li>
<div>게시자 : {{name}}</div>
<div class="content">{{content}}</div>
<div>좋아요 갯수 <span> {{like}} </span></div>
<div class="comment">
<div>{{comment}}</div>
</div>
</li>
</script>
js에서 replace로 치환하는 방법 대신,
handlebar 라이브러리로 사용해서 결과를 얻을 수 있다
<script>
var template = document.querySelector("#listTemplate").innerText;
var bindTemplate = Handlebars.compile(template); //bindTemplate은 메서드입니다.
</script>
compile은 함수를 반환하는 함수
데이터가 들어오면 바로 작업할 수 있도록
미리 만들어진 template 문자열을 가져와서 이 함수가 변수로 잠시 기억해 둠
정확히는, pre-compile이라고 말함
template 작업 시 이 용어를 많이 사용
이제 bindTemplate 변수를 이용하여 template 작업을 할 수 있음
전체 코드
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<h1> template using handlebar </h1>
<section class="show"></section>
<script type="myTemplate" id="listTemplate">
<li>
<div>게시자 : {{name}}</div>
<div class="content">{{content}}</div>
<div>좋아요 갯수 <span> {{like}} </span></div>
<div class="comment">
<div>{{comment}}</div>
</div>
</li>
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"
integrity="sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
var data = {
"id": 88,
"name": "crong",
"content": "새로운 글을 올렸어요",
"like": 5,
"comment": "댓글이다"
};
var template = document.querySelector("#listTemplate").innerText;
// pre-compile
var bindTemplate = Handlebars.compile(template); //bindTemplate은 메서드입니다.
console.log(bindTemplate);
var resultHTML = bindTemplate(data);
console.log(resultHTML);
var show = document.querySelector(".show");
show.innerHTML = resultHTML;
</script>
</body>
</html>
배열이 포함된 경우
예를 들어 comment가 1개 이상일 때
var data = {
"id" : 88,
"name" : "crong",
"content" : "새로운글을 올렸어요",
"like" : 5,
"comment" : ["댓글이다", "멋진글이네요", "잘봤습니다"]
};
반복문을 넣어서 처리
each 부분을 자세히보자
handlebar 라이브러리의 문법. #을 붙여서 헬퍼 기능임을 명시.
/each를 만날 때 까지 반복이 일어남
이 문법을 이용해 <div class="comment">를 다음과 같이 수정
<script type="myTemplate" id="listTemplate">
<li>
<div>게시자 : {{name}}</div>
<div class="content">{{content}}</div>
<div>좋아요 갯수 <span> {{like}} </span></div>
<div class="comment">
<h3>댓글목록</h3>
{{#each comment}}
<div>{{@index}}번째 댓글 : {{this}}</div>
{{/each}}
</div>
</li>
</script>
data 자체가 많아진 경우
var data = [
{"id" : 88, "name" : "crong", "content" : "새로운글을 올렸어요", "like" : 5, "comment" : ["댓글이다", "잘했어요"]},
{"id" : 28, "name" : "hary", "content" : "전 오늘도 노래를 불렀어요", "like" : 0, "comment" : ["제발고만..","듣고싶네요 그노래"]},
{"id" : 23, "name" : "pororo", "content" : "크롱이 항상 말썽을 피워서 행복해~", "like" : 4, "comment" : []},
{"id" : 5, "name" : "pobi", "content" : "물고기를 한마리도 잡지 못하다니..", "like" : 5, "comment" : ["댓글이다", "멋진글이네요", "잘봤습니다"]}
];
!! 핵심은 bindTemplate()을 루프를 돌면서 여러 번 실행하고 차곡차곡 합친다는 점
1. forEach 사용
var innerHtml = "";
data.forEach(function (item, index) {
innerHtml += bindTemplate(item);
});
2. reduce를 사용
var innerHtml = data.reduce(function(prve, next) {
return prve + bindTemplate(next);
}, "");
전체 코드
style 추가
<!DOCTYPE html>
<html lang="en">
<head>
<style>
li {
list-style: none;
padding: 10px;
border-top: 2px solid gray;
}
</style>
</head>
<body>
<h1> template using handlebar </h1>
<section class="show"></section>
<script type="myTemplate" id="listTemplate">
<li>
<div>게시자 : {{name}}</div>
<div class="content">{{content}}</div>
<div>좋아요 갯수 <span> {{like}} </span></div>
<div class="comment">
<h3>댓글목록</h3>
{{#each comment}}
<div>{{@index}}번째 댓글: {{this}}</div>
{{/each}}
</div>
</li>
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"
integrity="sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
var data = [
{ "id": 88, "name": "crong", "content": "새로운글을 올렸어요", "like": 5, "comment": ["댓글이다", "잘했어요"] },
{ "id": 28, "name": "hary", "content": "전 오늘도 노래를 불렀어요", "like": 0, "comment": ["제발고만..", "듣고싶네요 그노래"] },
{ "id": 23, "name": "pororo", "content": "크롱이 항상 말썽을 피워서 행복해~", "like": 4, "comment": [] },
{ "id": 5, "name": "pobi", "content": "물고기를 한마리도 잡지 못하다니..", "like": 5, "comment": ["댓글이다", "멋진글이네요", "잘봤습니다"] }
];
var template = document.querySelector("#listTemplate").innerText;
var bindTemplate = Handlebars.compile(template);
//loop를 돌면서 bindTemplate을 실행
var resultHTML = data.reduce((prev, next) => {
return prev + bindTemplate(next);
//next가 다음 번째의 prev가 된다
}, "");
var show = document.querySelector(".show");
show.innerHTML = resultHTML;
</script>
</body>
</html>
조건 상황에 따른 처리
예로 댓글이 없는 경우에는 다른 메세지로 처리해야 한다면?
template은 말 그대로 고정되어 있지만 handlebar에서 if를 사용하여 처리 가능
<script type="myTemplate" id="listTemplate">
<li>
<div>게시자 : {{name}}</div>
<div class="content">{{content}}</div>
<div>좋아요 갯수 <span> {{like}} </span></div>
<div class="comment">
<h3>댓글목록</h3>
{{#if comment}}
{{#each comment}}
<div>{{@index}}번째 댓글 : {{this}}</div>
{{/each}}
{{else}}
<div>댓글이 아직 없군요</div>
{{/if}}
</div>
</li>
</script>
참고
help function 사용
좋아요 개수가 5개 이상이면 "축하해요. 좋아요가 5개 이상입니다"라믄 문자열을 추가해보겠습니다
likes 라는 커스텀 항목을 추가했습니다.
<script type="myTemplate" id="listTemplate">
<li>
<div>게시자 : {{name}}</div>
<div class="content">{{content}}</div>
{{#likes like}}
{{like}}
{{/likes}}
<div class="comment">
<h3>댓글목록</h3>
{{#if comment}}
{{#each comment}}
<div>{{@index}}번째 댓글 : {{this}}</div>
{{/each}}
{{else}}
<div>댓글이 아직 없군요</div>
{{/if}}
</div>
</li>
</script>
이제 다양한 조건을 설정하는 likes helper를 만들겁니다.
registerHelper를 이용하여 likes와 관련된 것들을 실행하게 해줍니다.
#likes를 만나면 "likes"로 등록된 함수를 찾아서 실행
Handlebars.registerHelper("likes", function (like) {
if (like > 4) {
return "<span>축하해요 좋아요가 " + like + "개 이상입니다!</span>";
} else if (like < 1) {
return "아직 아무도 좋아하지 않아요..";
} else {
return like + "개의 좋아요가 있네요";
}
});
전체 코드
<!DOCTYPE html>
<html lang="en">
<head>
<style>
li {
list-style: none;
padding: 10px;
border-top: 2px solid gray;
}
</style>
</head>
<body>
<h1> template using handlebar </h1>
<section class="show"></section>
<script type="myTemplate" id="listTemplate">
<li>
<div>게시자 : {{name}}</div>
<div class="content">{{content}}</div>
{{#likes like}}
{{like}}
{{/likes}}
<div class="comment">
<h3>댓글목록</h3>
{{#if comment}}
{{#each comment}}
<div>{{@index}}번째 댓글 : {{this}}</div>
{{/each}}
{{else}}
<div>댓글이 아직 없군요</div>
{{/if}}
</div>
</li>
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"
integrity="sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
var data = [
{ "id": 88, "name": "crong", "content": "새로운글을 올렸어요", "like": 5, "comment": ["댓글이다", "잘했어요"] },
{ "id": 28, "name": "hary", "content": "전 오늘도 노래를 불렀어요", "like": 0, "comment": ["제발고만..", "듣고싶네요 그노래"] },
{ "id": 23, "name": "pororo", "content": "크롱이 항상 말썽을 피워서 행복해~", "like": 4, "comment": [] },
{ "id": 5, "name": "pobi", "content": "물고기를 한마리도 잡지 못하다니..", "like": 5, "comment": ["댓글이다", "멋진글이네요", "잘봤습니다"] }
];
Handlebars.registerHelper("likes", function (like) {
if (like > 4) {
return "<span>축하해요 좋아요가 " + like + "개 이상입니다!</span>";
} else if (like < 1) {
return "아직 아무도 좋아하지 않아요..";
} else {
return like + "개의 좋아요가 있네요";
}
});
var template = document.querySelector("#listTemplate").innerText;
var bindTemplate = Handlebars.compile(template);
//loop를 돌면서 bindTemplate을 실행
var resultHTML = data.reduce((prev, next) => {
return prev + bindTemplate(next);
//next가 다음 번째의 prev가 된다
}, "");
var show = document.querySelector(".show");
show.innerHTML = resultHTML;
</script>
</body>
</html>
'Web > Frontend' 카테고리의 다른 글
생성자 패턴으로 TabUI 만들기 (0) | 2021.07.07 |
---|---|
Clean Code (0) | 2021.07.06 |
jQuery 프레임워크에 대해 (0) | 2021.07.01 |
[JS] 객체리터럴, this, bind() (0) | 2021.07.01 |
[JS] 배열 메소드 (0) | 2021.07.01 |