728x90

Handlebars 다운로드 

https://handlebarsjs.com/installation/#downloading-handlebars

 

Installation | Handlebars

Installation There are a variety of ways to install Handlebars, depending on the programming language and environment you are using. npm or yarn (recommended) The reference implementation of Handlebars is written in JavaScript. It is most commonly installe

handlebarsjs.com

cdnjs click

최신버전 또는 원하는 특정 버전의 scritp tag를 copy해온다. 

<script defer type="text/JAVASCRIPT"

src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.8/handlebars.min.js"></script>

 

SPA(Single Page Application)  

서버로부터 완전히 새로운 페이지를 받아로딩하지 않고 

하나의 페이지에서 갱신이 필요한 부분만 동적으로 다시 작성하여 사용자와 상호작용하는 방식

 

1. 하나의 페이지에 여러 페이지에 들어갈 컨텐츠를 모두 만들고 

그 컨텐츠들을 숨겨놓았다가

<div id="guest-view-template" style="display: none;">

요청과 응답에 따라 보여줄 템플릿을 보여준다. 

 

2. Handlebars에서 지원하는 <script> 태그를 이용

 

<script id="guest-modify-form-template" type="text/x-handlebars-template">

<script> 태그내에 데이터를 모두 텍스트로 가지고 있다가 요청에 따라 

<script> 태그의 내용을 html로 파싱하여 콘텐츠를 출력해준다. 

 

 

 

Handlebars expressions

{{...}}

 

반복문

{{#each 반복할컬렉션}}

        컬렉션.guest_no를 출력하려면{{guest_no}}

{{/each}}

 

{{#each data}}

<tr class="guest_item">

<td width="50" align="center" bgcolor="ffffff" height="20" >{{guest_no}}</td>

<a href="#{{guest_no}}" class="guest_item_a" guest_no="124">{{guest_title}}

</a>

{{/each}}

<a href="#1">

href 속성에 #를 붙이면 페이지기반요청을 하지 않는다. 

여기서 #guest_no를 붙여준 이유는 

a 클릭이벤트 발생시 href 속성의 값에서  guest_no를 문자열 처리를 하여 얻어내고 

페이지 기반 요청 없이 /guests/{guest_no} URI 맵핑하는데 이용하기 위해서 사용했다.

 

{{#with 객체}}

        {{property}}

{{/with}}

#with는 프로퍼티에 접근할 객체를 지정하여 

프로퍼티를 기술할 때 객체를 생략할 수 있게 해준다. 

{{#with data.[0]}}

<form name="f" id="guest_view_form" method="post">

<input type="hidden" name="guest_no" value="3">

<table border="0" cellpadding="0" cellspacing="1" width="590"

bgcolor="BBBBBB">

<tbody>

<tr>

<td width="100" align="center" bgcolor="E6ECDE" height="22">번호</td>

<td width="490" bgcolor="ffffff" align="left"

style="padding-left: 10px">{{guest_no}}</td>

</tr>

<tr>

<td width="100" align="center" bgcolor="E6ECDE" height="22">이름</td>

<td width="490" bgcolor="ffffff" align="left"

style="padding-left: 10px">{{guest_name}}</td>

</tr>

</tbody>

</table>

{{/with}}

여기선 data 배열에 있는 원소들 중 0번 인덱스에 접근하여 guest_no, guest_name에 접근한다. 

{{내에서 배열의 인덱스에 접근할 땐 }}

array[index]가 아니라 array.[index] 으로 기술한다. 

 

 

++<태그 내에 정의된 속성 이외에 커스텀으로 속성을 추가할 수 있다. >

<input type="button" value="수정"

id="btn_guest_modify_form" guest_no="{{data.[0].guest_no}}">

modify action을 위한 guest_no 

 

 

 

 

handlebars에 함수 등록하기 

function addCustomFunctionHandlebars(){

//Handlebars 함수 등록

Handlebars.registerHelper('substring',function(str,start,end){

return str.substring(start,end);

});

Handlebars.registerHelper('toUpperCase',function(str){

return str.toUpperCase();

});

}

Handlebars.registerHelper('funcName',funcArg); 

<td width="120" align="center" bgcolor="ffffff">{{toUpperCase guest_name}}</td>

<td width="120" align="center" bgcolor="ffffff">{{substring guest_date 0 10}}</td>

{{...}} 표현식에서 함수와 인자를 사용할 땐

funcName param1 param2 param2 

공백으로 구분해준다.

 

 

페이지 내 컨텐츠 영역을 갱신해주는 메소드

function render(templateId="#guest-main-template",jsonResult={},contentId="#content")

{//templateId="", contentId="" >>default값 설정

addCustomFunctionHandlebars();

let templateHtml = document.querySelector(templateId).innerHTML;

let bindTemplate =Handlebars.compile(templateHtml);

let resultTemplate =bindTemplate(jsonResult);

document.querySelector(contentId).innerHTML = resultTemplate;

}

<script> 태그 내에 작성한 템플릿의 HTML (컨텐츠 영역에 표시할 템플릿)

Handlebars.compile(템플릿HTML) 을 사용하면 

Handlebars 엔진이 expressions에 맞춰 데이터를 바꿔 출력할 수 있도록 함수로 만들어 반환해주면  

json 데이터를 그 함수에 넣어주면 HTML을 완성해준다. 

완성된 HTML을 content 영역에 innerHTML 해준다. 

 

++함수를 정의할 때 파라메터에 값을 지정해주면 default 값으로 지정해준다. 

 

버튼 또는 돔 객체에 addEventListener('click', funcArg) 으로 템플릿을 바꿔주는 render 메소드를 실행하는 익명함수를 작성해준다. 

menuGuestWriteForm.addEventListener('click', function(e) {

View.render('#guest-write-form-template');

e.preventDefault();

});

이때 버튼이 페이지기반 요청을 Default로 한다면 event.preventDefault() 함수로 페이지 기반 요청을 막아줘야 한다. 

 

document.addEventListener('click', function(e) {

if (e.target.id == 'btn_guest_write_action') {

 }

if (e.target.classList.contains('guest_item_a')) {

}

 

만약 click 이벤트를 등록해야할 객체가 <script> 태그에 속한다면 

그 템플릿이 HTML로 올라오기 전엔 접근할 수 없다. 

 

event가 발생할 땐 window에서부터 타겟까지 타고 내려와 window로 bubble되며 이벤트가 발생하는 점을 이용하면

document.에 이벤트 등록을 하면 document 내의 모든 객체에서 들어오는 click 이벤트를 받아 처리할 수 있다. 

 

document에서 이벤트를 받아 이벤트의 타겟에 접근해서 <script> 태그 내의 객체의 이벤트가 발생하는 경우도 

이벤트 등록을 할 수 있다. 

 

if (e.target.classList.contains('guest_item_a')) {

if(e.target.href.indexOf('#')>=0){

let guest_no = e.target.href.substring(e.target.href.indexOf("#")+1);

//e.preventDefault(); #요청은 페이지기반 요청 아니라 필요없다.

let sendJsonObject = {};

/**********ajax 요청 **********/

Request.ajaxRequest(RequestURL.GUEST_DETAIL.method,

RequestURL.GUEST_DETAIL.url.replace('@guest_no',guest_no),

function(responseJsonObject) {

if (responseJsonObject.status == 1) {

//쓰기 성공시 리스트 클릭 이벤트 발생

View.render('#guest-view-template',responseJsonObject);

} else {

alert(responseJsonObject.msg);

}

},

sendJsonObject);

}

}

이전에 href="#{{guest_no}}"에서 받은 #1 에서 #를 제외한 나머지 {{guest_no}}를 구하여 URL에 붙여준다.

const GUEST_DETAIL = { method: 'GET', url: 'guests/@guest_no' };

 

export function ajaxRequest(method,url,callbackFunction,sendJsonObject={}) {

let xhr = new XMLHttpRequest();

xhr.open(method, url);

xhr.setRequestHeader('Content-type', 'application/json;charset=UTF-8');

xhr.onload = function() {

callbackFunction(JSON.parse(xhr.responseText));

}

xhr.send(JSON.stringify(sendJsonObject));//js에서는 키값에 ""필요없고 ''도 허용하지만 server측에선 ""필수기 때문에

}

ajaxRequest는 ajax 요청하는 과정을 함수로 추출하였다. 

이 과정은 추후 라이브러리를 사용하여 처리 가능하다. 

 

 

 

html 파일에서 module 사용하기 

<script src="js/app.js" type="module"></script>

type="javascript"대신 "module" 사용 

module을 사용하면 돔트리가 다 생성되고 난 후에 실행된다.

++type= "module"과 "javascript"

 

module 은 import, export 사용 가능 

module 은 독립적인 scope을 가져 프로퍼티는 module의 scope에 등록된다.

 

 

모듈은 모듈만 import 할 수 있다.

import * as View from "./view.js";

모듈에서 다른 모듈 import 하기 

as View : "./view.js"로부터 import 모든 프로퍼티를 View라는 이름으로 사용하겠다

import {render} from "./view.js";    하면 render만 임포트

다른 모듈의 특정 메소드나 변수만 import 하고 싶은 경우 {..} 로 지정해줄 수 있다. 

export 하는 파일에서는 export 프로퍼티를 지정해줄 수 있다. 

프로퍼티 앞에 export를 붙이거나 

export{property1, property2...} 으로 지정한다.

 

 

 

 

'Web' 카테고리의 다른 글

YAML Converter  (0) 2023.10.11
HTML5 Basic  (0) 2023.09.19
Mybatis Mapper  (0) 2023.09.19
MyBatis Config  (0) 2023.09.19
AJAX Asynchronous Javascript And XML  (0) 2023.09.18

+ Recent posts