지난 글을 마무리 했을 때의 js는 다음과 같은 상태였다.
/* server.js */
const express = require('express')
const app = express()
const nunjucks = require('nunjucks')
app.set('view engine', 'html')
nunjucks.configure('views', {express:app})
app.use(express.urlencoded({extended:true}))
const list = require('./boardData')
const data = [...list.data]
// list.data라는건 가져온 객체 list 안의 data (배열)
// main
app.get('/', (req, res) => {
res.render('index.html')
})
// board
app.get('/board/list', (req, res) => {
res.render('board_list.html', {
list:data
})
})
// write
app.get('/board/write', (req, res) => {
res.render('board_write.html', {
list:data
})
})
app.post('/board/write', (req, res) => {
let item = {...req.body}
data.push(item)
res.redirect('/board/list')
})
이제 여기서 제목을 클릭하면 글 내용을 볼 수 있게 해주는 기능, 글을 삭제하는 기능, 수정하는 기능을
차례로 추가해볼 것이다.
1. 글 보기 페이지
우선 각각의 글의 내용을 보여주는 웹 페이지의 html을 다음과 같이 작성해주자.
/* board_view.html */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1><a href='/'>logo</a></h1>
<h2>글보기 페이지</h2>
<ul>
<li>
<strong>글제목</strong>
: {{data.subject}}
</li>
<li>
<strong>작성자</strong>
: {{data.username}}
</li>
<li>
<strong>작성일</strong>
: {{data.date}}
</li>
</ul>
<a href='/board/list'>목록가기</a>
이제 리스트 페이지에서 제목을 클릭하면 해당 글을 볼 수 있는 페이지로 이동하는 기능을 넣어줘야 한다.
리스트 페이지의 board_list.html에서 글 제목에 해당하는 부분을 다음과 같이 수정해주자.
/* board_list.html */
<td><a href='/board/view?index={{num}}'> {{item.subject}} </a></td>
anchor 태그의 uri를 보면 '?' 이후로 index라는 변수를 선언했음을 알 수 있다.
유의해야 할 것은 이 num이라는 변수도, index라는 변수도 html에서 오는 것이고,
데이터를 string 형태로 넘겨주면 이를 서버가 요청 헤더의 body로 받아 인식할 수 있게 되는 것이다.
(정리하자면 uri에서 ? 이후의 텍스트를 서버가 요청의 body로 인식한다.)
그러면 이제 다시 server.js로 돌아와서 새로 인식한 변수를 활용해보자.
/* server.js */
app.get('/board/view', (req, res) => {
const index = req.query.index // get은 요청을 query로, post는 body로 써준다.
const view = data[index-1]
res.render('board_view.html', {
data:view,
index:index
})
})
코드 블럭 내에서 지역 변수 index와 view를 선언했다.
변수 index는 board_list.html에서 처음 선언되었고, 이를 포함한 anchor element를 클릭하면 /board/view로 이동한다.
단, 여기서 요청 헤더의 body에 데이터가 추가되는데,
board_list.html에서 ? 이후의 텍스트 index={{num}}를 함께 서버에 넘겨주게 된다.
이제 서버는 index라는 변수가 있다는 것을 알았다. (html의 index 변수를 의미함)
이 때부터 server.js에서 지역 변수 index를 선언시 요청의 body, 그 중에서도 index라는 변수를 가져다가 대입할 수 있다.
(server.js에 방금 const로 선언해준 index를 의미)
이 index는 게시판에 있는 글의 순서와 동일하므로
우리가 최초에 선언한 server.js의 전역 변수 data(배열)의 요소들의 순서와 정확히 일치한다.
그래서 이 index 변수를 이용해 전역 변수 data의 eleemnt중 원하는 요소 (객체)를 고를 수 있다.
const로 선언한 지역 변수 view를 그런 방식으로 선언해주었다.
변수에 대한 이해가 끝났다면 이제 요청에 대한 응답 코드를 작성해주면 된다.
board_view.html 문서를 불러오되, 여기에 들어갈 데이터는 지역 변수 view와 index에 의해 결정된다.
이 과정을 좀 더 간결히 정리하자면
> board_list에서 글을 클릭하면
> anchor element에 걸린 링크로 이동
> 서버에 요청을 보내는데, 이 요청의 body에는 board_list.html의 index 변수가 포함되어 있음.
> 이 index를 이용해 라우터에서 변수를 선언할 수 있게 됨. (지역 변수 index)
> server.js의 전역변수 data(배열)에서 선언한 지역 변수 index에 대응하는 요소를 골라준다. (data[index-1])
> 선별한 데이터들을 응답에 포함시켜 html과 함께 렌더링한다.
이게 가장 헷갈리는 부분이니 여러 번 읽어봐야 할 듯..
2. 글 삭제
다음으로 글을 삭제하는 기능을 구현해보자.
board/view 웹 페이지에서 삭제 버튼을 누르면 그 요청에 응답해 글을 삭제하고 board/list로 빠져나오게끔 해볼 것이다.
우선 server.js에 다음과 같이 삭제 uri에 대응하는 코드와 추가하고 연관된 html을 수정하자.
/* server.js */
app.post('/board/delete', (req, res) => {
const index = req.body.index-1
data.splice(index, 1)
res.redirect('/board/list')
})
지역 변수 index는 방금과 동일하게 board_view.html에서 요청 헤더의 body중 index를 가져왔다.
1을 빼준 이유는 전역 변수 data(배열)의 요소와 순서를 맞춰주기 위함이다.
변수의 값을 전달받으면 그 값에 해당하는 요소를 전역 변수 data(배열)로부터 제거하고 리스트 페이지로
리다이렉트 해준다.
이제 이 기능을 클릭/제출을 통해 시행할 수 있도록 html 문서에 다음을 추가해줘야 한다.
/* board_view.html */
<form method='post' action='/board/delete'>
<input type='hidden' name='index' value='{{index}}'>
<input type='submit' value='삭제하기'>
</form>
이렇게 해놓고 글 보기 페이지로 가면 삭제하기 버튼이 생겼음을 알 수 있다.
이 버튼을 눌러 요청을 제출하면 글의 index가 req.body에 포함되어 전달되고,
이 요청을 받은 server.js에서 (서버에서) 받은 변수값에 해당하는 요소를 전역 변수 data에서 제거한 후,
리스트 페이지로 리다이렉트 시킨다.
3. 글 수정
글 수정은 앞에서 한 삭제와 보기에서 한 내용을 적절히 조합해 사용하면 된다.
우선, board_view.html에 수정하기 버튼을 만들어 글 보기 페이지에서 수정 페이지에서 넘어가는 기능을 넣어주자.
/* board_view.html */
<a href='/board/update?index={{index}}'>수정하기</a>
글 수정 페이지에 대응할 html도 만들어준다.
/* board_update.html */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1><a href="/">logo</a></h1>
<h2> 글수정 페이지 </h2>
<form method = 'post' action="/board/update">
<input type="hidden" name="index" value="{{index}}">
<ul>
<li>
<strong>글제목</strong>
: <input type="text" name="subject" value="{{data.subject}}">
</li>
<li>
<strong>작성자</strong>
: <input type="text" name="username" value="{{data.username}}">
</li>
<li>
<strong>글제목</strong>
: <input type="text" name="data" value="{{data.date}}">
</li>
</ul>
<input type="submit" value="수정하기">
</form>
<a href="/board/list">목록보기</a>
</body>
</html>
수정하기 버튼을 누르면 /board/update로 이동시킬 코드를 server.js에 추가한다.
/* server.js */
app.get('/board/update', (req, res) => {
const index = req.query.index
const view = data[index-1]
res.render('board_update.html', {
data:view,
index:index
})
})
이렇게 한 후, board_view.html에서 수정하기 버튼을 누르면 글 수정 페이지로 이동한 후,
index값이 맞는 데이터를 가진 board_update.html을 렌더링해준다.
이제 수정된 데이터를 제출하면 그에 응답해 게시물 내용을 수정하고 글보기 페이지로 이동시켜주는 코드를 넣어보자.
/* server.js */
app.post('/board/update', (req, res) => {
const index = req.body.index
const item = {
subject:req.body.subject,
username:req.body.username,
date:req.body.date
}
date[index-1] = item
res.redirect(`board/view?index=${index}`)
})
글 수정 페이지로 이동 후,
우리가 원하는대로 input box를 수정한 후 제출하면 서버가 수정한 새로운 데이터들을 요청으로 받을 것이다.
이 때 요청으로 서버에 전달한 데이터는 객체 형태를 가진다.
받은 데이터들을 지역변수에 item에 담는다.
데이터는 각각의 key들은 이전과 동일하고 value값이 다른 객체 형태일 것이다.
이 객체로 원래 전역 변수 data안에 있던 객체를 (index값이 같은) 대체해준 후, 글보기 페이지로 redirect해준다.
'Nodejs > Server' 카테고리의 다른 글
Session #2 - 미들웨어 (0) | 2022.02.13 |
---|---|
Session #1 (0) | 2022.02.13 |
Server의 이해 - Cookie #2 (0) | 2022.02.08 |
Server의 이해 - Cookie #1 (0) | 2022.02.07 |
Javascript의 활용 - 게시판 서버 만들기 #1 (0) | 2022.02.06 |