1. 개요.

  • 댓글 영역은 크게 두 가지로 나뉨.
    • 기존 댓글을 보여주는 영역. (_list)
    • 새 댓글을 입력하는 영역. (_new)
  • 댓글 전체 영역, 즉 뷰(view). (_comments)

2. 뷰 페이지 삽입하기.

@Controller     // 컨트롤러 선언.
@Slf4j
public class ArticleController {
    @Autowired
    private ArticleRepository articleRepository;

    @GetMapping("/articles/{id}")
    public String show(@PathVariable Long id, Model model) {        // 단일 데이터 조회.
        Article articleEntity = articleRepository.findById(id).orElse(null);
        model.addAttribute("article", articleEntity);

        return "articles/show";
    }
}
  • 위의 컨트롤러가 상세 페이지를 보여달라는 요청을 받아 처리함.
    • show() 메서드가 /articles/{id}로 접속했을 때 보여주는 페이지반환하고 있음.
      • return "articles/show";
      • 해당 경로에 있는 파일이 특정 게시글의 상세 페이지임.

show.mustache

{{>layouts/header}}
<!--  글 상세 페이지  -->

<!-- 생략 -->

{{>comments/_comments}}
{{>layouts/footer}}
  • 댓글은 페이지 제일 밑에 위치하므로 푸터(footer) 바로 위에 댓글 뷰 파일을 삽입함.
    • 이렇게 해줌으로써 comments 디렉터리에 _comments.mustache 파일을 연결해서 상세 페이지에 댓글이 보이게 됨.

  • 디렉터리 생성 -> mustache 파일 생성.

_comments.mustache

<div>

    <!--  댓글 목록 보기  -->
    {{>comments/_list}}
    <!--  새 댓글 작성하기  -->
    {{>comments/_new}}
    
</div>
  • 여기서 <div> 태그는 웹 페이지의 레이아웃(전체적인 틀)을 만들 때 사용하는 태그.
    • 웹 페이지의 영역을 논리적으로 구분한다고 생각하면 됨.
    • <div>태그를 사용하면 각 공간에 구성 요소를 배치하고 CSS를 활용해서 스타일을 적용할 수 있음.

부트스트랩의 card 요소 사용.

_list.mustache

<div id="comments-list">
    {{#commentsDtos}}
        <div class="card m" id="comments-{{id}}">
            <div class="card-header">
                {{nickname}}
            </div>
            <div class="card-body">
                {{body}}
            </div>
        </div>
    {{/commentsDtos}}
</div>
  • <div id="comments-list">...</div>
    • 댓글 목록 전체를 보여주는 영역.
    • id="comments-list로 설정.
  • {{#commentsDtos}}...{{/commentsDtos}}
    • 조회한 댓글 목록에서 댓글을 하나씩 꺼내서 순회할 수 있도록.
    • commentsDtos가 만약 복수개의 데이터라면 mustache 문법 안쪽에 있는 내용을 반복.
  • div class="card m" id="comments-{{id}}">...</div>
    • 댓글 하나를 보여주는 영역.
      • "card"
        • 해당 영역을 카드 구조로 만듦.
      • id="comments-{{id}}"
        • 반복되는 commentsDtos에 있는 id값을 삽입해서 이 영역의 id를 comments-1, comments-2 등으로 설정.
        • Ex)
          commentsDtos(id=1, article=1, nickname=Kim, body=안녕)
          commentsDtos(id=2, article=1, nickname=Lee, body=하이)
          이럴 경우
          id="comments-1의 nickname에는 Kim, body에는 안녕
          id="comments-2의 nickname에는 Lee, body에는 하이
          이렇게 구성됨.
  • <div class="card-header">{{nickname}}</div>
    • 댓글 내에서 헤더 영역.
    • 닉네임 표시.
  • <div class="card-body">{{body}}</div>
    • 댓글 내에서 본문 영역.
    • 본문 표시.

3. 데이터 가져오기.

  • MVC 패턴에 따르면 사용자가 볼 화면(View)을, 컨트롤러(Controller)가 반환하는데 화면에 필요한 데이터는 모델(Model)에 등록해야 함.
  • 페이지에서 사용할 변수는 반드시 모델에 등록해야 사용할 수 있음.
@Controller     // 컨트롤러 선언.
@Slf4j
public class ArticleController {
    @Autowired
    private ArticleRepository articleRepository;
    @Autowired
    private CommentService commentService;	// 1번

    @GetMapping("/articles/{id}")
    public String show(@PathVariable Long id, Model model) {        // 단일 데이터 조회.
        Article articleEntity = articleRepository.findById(id).orElse(null);
        List<CommentDto> commentDtos = commentService.comments(id);     // 2번
        model.addAttribute("article", articleEntity);       
        model.addAttribute("commentDtos", commentDtos);		// 3번.
        return "articles/show";
    }
}
  • 1번
    • CommentService 객체를 @Autowired를 이용해서 외부에서 주입.
  • 2번
    • comments(id) 메서드를 호출해서 댓글 목록 조회.
  • 3번
    • 조회한 댓글 목록(commentDtos)을 모델에 등록.
    • model.addAttribute("변수명", 변수값); : 변수값을 "변수명"이라는 이름으로 추가.

  • 댓글 사이의 폭을 늘려주기.
    • _list파일에서 card 요소의 바깥 여백(margin)을 2로 설정.
      • marginCSS속성이지만 부트스트랩의 m-1, m-2,...m-* 클래스로 간편히 적용할 수 있음.

profile
Every cloud has a silver lining.

0개의 댓글