Javascript

SPA AJAX Request With JQuery

최고다최코딩 2023. 9. 25. 19:26
728x90

이전에 만들었던 버전은 핸들바의 script 태그를 이용해 메인 html에 여러 페이지의 템플릿을 숨겨두고 요청에 따라 템플릿을 보여주었는데 이번에는 네비게이터를 만들었다. 

href의 #해시 요청과 button의 클릭 이벤트 발생시 hash를 바꿔주어 hashchange 이벤트가 발생하면 

navigator에서 hash의 url을 확인하고 템플릿을 꺼내고 필요한 AJAX 요청을 한다. 

 

function navigate() {

const hash = window.location.hash;

const path = hash.substring(1);

let html = "";

hash는 #로 시작하므로 지저분한 #을 떼주고 path만 남도록 substring으로 정리해주었다. 

템플릿을 받을 html 변수를 생성

if (path == '/guest_main') {

html = guest_main();

} else if (path == '/guest_list') {

ajaxRequest(GUEST_LIST.method,GUEST_LIST.url,function(responseJsonObject){

html = guest_list(responseJsonObject);

$('#content').html(html);//????

});

}

이런식으로 path를 구분하여 main으로 보낼지 list로 보낼지 결정한다. 

문제는 list의 ajax 요청이다. 

ajax 요청이라하면 요청을 하고 응답을 받는 동안 쓰레드가 계속 돌아야하는데 

ajax 요청의 콜백함수에서 guest_list의 템플릿에 json 데이터를 핸들바로 바인딩하여 완성된 템플릿을 받아 html에 초기화 시킬때까지 기다리게 된다. 

이문제는 추후 promise 객체로 해결한다. 

 

여기서 guest_main, guest_list 함수는 

import { guest_main } from "./template-guest-main.js";

import { guest_write_form } from "./template-guest-write-form.js";

import { guest_list } from "./template-guest-list.js";

import { ajaxRequest } from "./request.js";

import {GUEST_DETAIL,GUEST_MODIFY_ACTION,GUEST_MODIFY_FORM,

GUEST_REMOVE_ACTION,GUEST_LIST,GUEST_WRITE_ACTION} from "./request-url.js";

template을 반환하는 함수를 가진 js 모듈을 import한 것이다.

 

템플릿 함수는 대략 이런 구조를 가진다.

let htmlTemplate = `

<table >

<tbody>

<tr>

<td>번호</td>

<td>제목</td>

<td>이름</td>

<td>날짜</td>

</tr>

{{#each data}}

<tr class="guest_item">

<td>{{guest_no}}</td>

<td>

<a href="#/guest_detail/{{guest_no}}" class="user guest_item_a">{{guest_title}}

</a>

</td>

<td>{{toUpper guest_name}}</td>

<td>{{substring guest_date 0 10}}</td>

</tr>

{{/each}}

</tbody>

</table>`;

let bindTemplate = Handlebars.compile(htmlTemplate);

let resultTemplate = bindTemplate(responseJsonObject);

return resultTemplate;

html 템플릿 텍스트를 Handlebars.compile 하여 만들 bindTemplate 함수에 Ajax 요청에 대한 응답으로 받은 responseJsonObject를 넣어준뒤 완성된 템플릿인 resultTemplate을 만들어반환한다.

 

else if(path.startsWith('/guest_modify_form/')){

const guest_no = path.substring(path.lastIndexOf('/')+1);

ajaxRequest(GUEST_MODIFY_FORM.method,GUEST_MODIFY_FORM.url.replace('@guest_no',guest_no),function(responseJsonObject){

html = guest_modify_form(responseJsonObject);

$('#content').html(html);

})

}

수정폼에선 기존의 데이터를 가져와야하기 때문에 guest_no가 필요하다 

guest_no는 view(detail)에서 가져온다.

<input type="button" data-navigate="/guest_modify_form/{{data.[0].guest_no}}" value="수정" >

view 버튼 중에 수정 버튼은 data-navigate라는 custom attribute를 가지고 있다. 

버튼을 클릭하면 클릭이벤트가 발생하는데 이 클릭이벤트가 발생하면 해쉬체인지 이벤트가 발생하도록 해준다.

$(document).on('click',function(e){

if(e.target.getAttribute('data-navigate')){

window.location.hash=e.target.getAttribute('data-navigate');

}

});

data-navigate의 /guest_modify_form/guest_no 를 가져올수 있게된다.

navigate에서는 여기서 가져온 guest_no로 restController의 guests/guest_no에 필요한 guest_no를 채울수 있게된다.

else if(path.startsWith('/guest_modify_action/')){

const guest_no = path.substring(path.lastIndexOf('/')+1);

데이터 검증 생략

let sendJsonObject = {

guest_no: $('#guest_modify_form [name="guest_no"]').val(),

guest_date: "",

guest_name: $('#guest_modify_form [name="guest_name"]').val(),

guest_email: $('#guest_modify_form [name="guest_email"]').val(),

guest_homepage: $('#guest_modify_form [name="guest_homepage"]').val(),

guest_title: $('#guest_modify_form [name="guest_title"]').val(),

guest_content: $('#guest_modify_form [name="guest_content"]').val()

};

 

ajaxRequest(GUEST_MODIFY_ACTION.method,GUEST_MODIFY_ACTION.url.replace('@guest_no',guest_no),function(responseJsonObject){

if (responseJsonObject.status == 1) {

//쓰기 성공시 HashChange 이벤트 발생

window.location.hash='/guest_detail/'+guest_no;

} else {

alert(responseJsonObject.msg);

}

},sendJsonObject)

}

ajax request가 성공하면 

window.location.hash를 변경해주어 guest_detail 템플릿을 뿌리도록 이벤트를 발생시킨다.