본문 바로가기

프로그래밍/Node.js

[Do it! Node.js 프로그래밍] 14일차

1. 공부한 범위


[14] 게시판 만들기



2. 공부한 내용


[14] 게시판 만들기

 

14-1 스키마를 추가하고 페이지 단위 조회 방식 이해하기

 

- 우선 게시판을 위한 스키마를 정의한다.

 

- 컬럼에는 글 제목, 글 내용, 글쓴이 (정보를 참조할 수 있도록 ObjectId가 저장된다.), 글의 태그, 글을 쓴 일시, 글을 수정한 일시, 댓글이 있다.

- 위 스키마에는 두 가지 특이한 점이 있다.

1) writer 컬럼에 저장되는 데니터 타입이 mongoose.Schema.ObjectId다. 이는 사용자 정보가 users 컬렉션에 저장되어 있고 이 컬렉션의 문서 객체 중 ObjectId 속성값이 writer 컬럼에 저장된다는 뜻이다.

2) comments 컬럼 안에 다시 객체가 저장된다. 댓글 컬럼은 별도의 컬렉션에 저장하는 방식을 사용할 수도 있으나 이 스키마에서는 한 컬렉션 안에 함께 포함시켜두었다.

- 1)와 같은 경우를 다른 컬렉션을 가리키는 레퍼런스라고 하며, 몽고디비에서 여러 컬렉션 사이의 데이터들을 연결해주는 키 역할을 한다.

 

- 스키마 객체에 정의된 path 메소드를 이용하여 컬럼을 지정한 후 required 메소드를 통해 필수 입력 컬럼으로 만든다.

- 새 인스턴스 메소드를 추가하는데, 각각 글 저장, 댓글 추가, 댓글 삭제다.

- push() 메소드를 사용하면 댓글을 저장할 수 있으며, 댓글 삭제시 전달받은 id값과 splice() 메소드를 활용하면 해당 인덱스의 댓글을 지울 수 있다.

 

- id값으로 원하는 댓글의 인덱스를 찾는 코드

- post_schema에서 인덱스를 찾는 코드를 사용하기 때문에 require를 통해 해당 모듈을 사용할 수 있도록 만든다. (var utils = require('../utils/utils');)

 

- static 메소드를 추가하면 모델 객체에서 사용이 가능해지며 load와 list 메소드를 추가한다.

 

- load 메소드는 id값으로 객체를 찾는 기능을 하며, findOne 메소드를 호출하는데 load 함수 안에서 populate 메소드를 함께 호출하고 있다.

- populate : ObjectId로 참조한 다른 컬렉션의 객체를 가져와 데이터를 채워준다.

- 게시판의 글들을 저장한 posts 컬렉션에는 writer 컬럼이 있고 해당 컬럼의 값으로 ObjectId가 저장된다. 이 값은 users 컬렉션에 들어있는 사용자 데이터 객체 중 하나와 같기 때문에 populate 메소드가 호출되면 해당 ObjectId값으로 users 컬렉션에서 검색 후 결과 데이터를 객체에 할당하게 된다.

 

페이지 단위로 조회하기

 

- list 메소드는 모든 데이터를 조회할 때 사용한다. 검색된 데이터가 너무 많아 문제가 생길 경우 조건을 추가해 일부 데이터만 조회할 수 있도록 제한할 수도 있다.

- pagination은 페이지 단위로 데이터를 조회할 수 있도록 만들어준다.

 

- 한 번에 보이는 페이지 수는 10개로 제한한다.

- 전체 페이지 수는 전체 글 수를 한 페이지에 보이는 글 목록의 수로 나눈다.

- 전체 글의 개수는 count 변수에, 한 페이지당 글 개수는 perPage, 전체 페이지 개수 계산값은 pageCount, 현재 조회중인 페이지의 인덱스값은 page에 담아둔다.

- 웹 브라우저에 조회 요청을 할 경우 page와 perPage값만 전달해도 서버에서 전체 글의 개수나 전체 페이지 개수를 계산해 결과물 산출이 가능하다.

- posts 컬렉션에서는 skip 속성이 들어있으며, 이는 페이지 인덱스 * 한 페이지당 글 수만큼 건너띌 수 있도록 해준다.

 

14-2 글쓰기와 글 조회 기능 만들기

 

- 글쓰기를 위한 라우팅 함수 addpost를 작성한다.

 

- addpost 메소드를 호출하면 데이터베이스에 글이 추가되며 클라이언트로부터 제목, 내용, 글쓴이 정보를 전달받는다.

- 글쓴이에 대해서는 데이터를 직접 저장하는 대신에 user 컬렉션의 사용자 데이터를 참조해 ObjectId만 저장해야 한다. 그렇기 때문에 이메일 주소를 사용해 user 컬렉션에서 객체를 조회 후 글쓴이 객체가 존재할 경우 그곳에 저장을 수행한다.

- redirect 메소드를 통해서는 저장한 글을 사용자에게 응답으로 보내주게 된다.

 

- showpost 함수에서는 저장된 글의 ObjectId값이 id 파라미터로서 전달되기 때문에 이를 이용해 글 객체를 조회할 수 있다.

- 글 객체를 발견한다면 showpost 뷰 템플릿을 사용해 자동으로 웹 문서를 만든 후 클라이언트에 응답으로 보낸다.

 

- showpost.ejs 파일

- 데이터베이스 내에 저장된 글을 보여줄 때는 그냥 출력하는 방법도 있지만 Semantic UI와 같이 추가적인 UI 효과를 입히는 방식을 사용할 수도 있다.

- HTML 태그를 해석해 웹 문서 형태로 보여주는 다양한 jQuery라이브러리가 있는데 이 중 cleditor를 사용해본다.

- 글쓰기 기능을 만들 때에는 ckeditor를 사용한다.

 

- addpost.html 파일

- ckeditor 라이브러리를 사용하게 되면 단순 입력상자인 textarea 태그가 글자의 속성을 바꿀 수 있는 입력상자로 바뀌어 글자를 이쁘게 꾸밀 수 있도록 바뀐다.

 

14-3 페이지 단위로 글 목록 조회하기

 

- 게시판 글 목록을 조회하는 기능의 제작순서

1) 라우팅 함수 제작

2) config.js에 라우팅 함수 등록

3) 응답 웹 문서를 구성할 뷰 템플릿 제작

4) 글 목록 조회를 요청하는 웹 페이지 제작

 

1단계 - 라우팅 함수 제작

 

- listpost 함수를 post.js 내부에 추가한다.

 

- 클라이언트로부터 전달받은 데이터는 현재 페이지 인덱스와 한 페이지에 보여줄 글의 개수인 page와 perPage다.

- 응답 웹 페이지를 위해서는 전체 글 개수를 알아야 하기 때문에 모델 객체의 count 메소드를 호출해 전체 글 개수를 확인한다.

 

2단계 - config.js 파일에 라우팅 함수 등록

 

 

- get과 post 방식을 모두 지원하고자 한다면 똑같은 코드 두 줄을 추가할 때 위와 같이 type 속성의 값만 변경하면 된다.

 

3단계 - 응답 웹 문서를 구성할 뷰 템플릿 제작

 

 

- 뷰 템플릿에서는 글 제목과 작성자, 작성일 등을 리스트 형태로 보여준다.

- posts 변수 안의 데이터는 for문을 통해 보여줄 수 있으며, 각 글 앞에 붙는 번호는 전체 글 개수 값을 사용해 계산 후 화면에 적용한다.

 

- 글 목록 아래에 있는 페이지 선택 버튼을 표시하는 부분이다.

- 코드의 길이가 길어진 이유는 두 가지로 나눌 수 있다.

1) 현재 보는 페이지 번호와 색상을 다른 번호와 다르게 하고 선택할 수 없도록 해야 한다.

2) 첫 페이지 또는 끝 페이지 버튼도 해당 페이지가 열려있는 상태에서는 비활성화되어있어야 한다.

- 페이지 단위 처리가 복잡하다 생각되면 노드에서 제공하는 pagination 패키지를 활용하는 방법도 있다.

 

4단계 - 글 목록 조회를 요청하는 웹 페이지 제작

 

- listpost.html 파일을 만들며, 해당 파일에는 단순히 조회 요청에 필요한 버튼만 넣는다.

- 게시판 목록 조회를 요청하는 기능은 보통 메인 페이지나 로그인 페이지를 통한다. 그렇기 때문에 웹 문서 내에 버튼 하나만 덩그러니 놓는 경우는 거의 없다.

- 위 단계들 외에 댓글 쓰기, 댓글 표시하기 기능 등을 넣으면 완전한 게시판이 완료된다.