[JHipster] CRUD 게시판 만들기 - 8 (Delete)

Junseo Kim·2019년 10월 25일
0

필요한 목록

  • src -> main -> java -> com.mycompany.myapp -> domain -> [DB 테이블과 연결할 class 파일]
  • src -> main -> java -> com.mycompany.myapp -> repository -> [repository interface 파일]
  • src -> main -> java -> com.mycompany.myapp -> web.rest -> [resource 파일(http request를 받아오는 곳)]
  • src -> main -> resources -> config -> liquibase -> changelog -> [.xml파일(테이블 구조)]
  • src -> main -> resources -> config -> liquibase -> master.xml(만들어준 .xml 파일 include)
  • src -> main -> webapp -> app -> layouts -> navbar -> navbar.component.html(메뉴 추가)
  • src -> main -> webapp -> app -> shared -> model -> [.model.ts 파일]
  • module 파일(만들어 준 후, 상위 모듈에서 import)
  • route 파일
  • service 파일
  • component.ts 파일(CRUD 각각)
  • component.html 파일(CRUD 각각)

Delete 기능 구현하기

마지막으로 delete 기능을 구현해보겠다. main 페이지의 Delete 버튼을 누르면 게시글이 삭제되고, DB에서도 삭제되도록 구현하여야한다.

스크린샷 2019-10-25 오전 10.54.27.png

delete 기능은 이전까지와는 조금 다르다. 삭제 버튼 클릭 시, 정말로 삭제할거냐는 alert 창을 띄워주고, 거기서 확인을 누르면 실제로 삭제되도록 구현해야한다.

board.component.html의 Delete 부분을 보자.

스크린샷 2019-10-25 오전 10.57.13.png
outlets는 기존 컴포넌트를 유지해두고, popup으로 새로운 컴포넌트를 load 해오는 것이다. 즉, 상위 컴포넌트 위에 하위 컴포넌트를 겹쳐서 띄우는 것이다.

board.route.ts에 delete를 추가해야하는데, 새로운 컴포넌트를 로드하므로, 새로운 라우터로 선언해주겠다.

스크린샷 2019-10-25 오후 12.17.15.png

라우터를 추가하였으므로, board.module에도 추가해주어야한다.

스크린샷 2019-10-25 오전 11.05.38.png

boardPopupRoute에서 BoardDeletePopupComponent로 연결되므로, BoardDeletePopupComponent도 선언해주어야한다. board-delete-dialog.component.ts 의 BoardDeleteDialogComponent밑에 BoardDeletePopupComponent를 만들어주겠다.

스크린샷 2019-10-25 오전 11.18.16.png

만들어준 component는 module에도 추가해줘야한다.

스크린샷 2019-10-25 오전 11.18.49.png

또 entryComponents에 BoardDeleteDialogComponent도 넣어줘야한다.

스크린샷 2019-10-25 오전 11.53.38.png

그럼, 만들어준 route가 활성화 되고, BoardDeletePopupComponent로 연결된다. BoardDeletePopupComponent의 ngOnInit에서 activatedRoute로 modalService의 open을 통해 BoardDeleteDialogComponent를 열어준다. 그럼 BoardDeleteDialogComponent에 연결된 html파일이 팝업으로 출력된다.

스크린샷 2019-10-25 오전 11.30.50.png

팝업으로 출력될 html 파일을 먼저 구현해주겠다.

//board-delete-dialog.component.html

<form name="deleteForm" (ngSubmit)="confirmDelete(board.id)">
    <div class="modal-header">
        <h4 class="modal-title">Confirm delete operation</h4>
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true"
                (click)="clear()">&times;</button>
    </div>
    <div class="modal-body">
        <jhi-alert-error></jhi-alert-error>
        <p id="jhi-delete-board-heading">Are you sure you want to delete this Board?</p>
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="clear()">
            <fa-icon [icon]="'ban'"></fa-icon>&nbsp;<span>Cancel</span>
        </button>
        <button id="jhi-confirm-delete-board" type="submit" class="btn btn-danger">
            <fa-icon [icon]="'times'"></fa-icon>&nbsp;<span>Delete</span>
        </button>
    </div>
</form>

BoardDeleteDialogComponent에 board를 선언해주고, confirmDelete와 clear 메소드를 구현해주어야한다.

먼저 만들어 둔 model로 board를 선언해주고, service와 연결해야하므로 BoardService도 생성자에 넣어준다. ngOnInit은 처음 component가 호출되었을 때, popup component에서 실행되었으므로 지워준다.

//board-delete-dialog.component.ts

//...
@Component({
  selector: 'jhi-board-delete-dialog',
  templateUrl: './board-delete-dialog.component.html'
})
export class BoardDeleteDialogComponent {
  board: IBoard;
  
  constructor(protected boardService: BoardService, public activeModal: NgbActiveModal, protected eventManager: JhiEventManager) {}

}

//...

activeModal을 닫아주는 clear(pop up 우측 상단 x 버튼)를 구현해주고, BoardService의 delete(구현해야함)를 호출하고, response가 오면 activeModal을 닫아주는 confirmDelete도 구현한다. confirmDelete의 eventManager.broadcast 안의 name 값은 board.component.ts의 registerChangeInBoards에서 기다리고 있다가 name값을 받으면 list를 새로 load 해주어 delete된 결과가 화면에 반영되게한다.

//board-delete-dialog.component.ts

import {Component, OnDestroy, OnInit} from '@angular/core';
import {
  NgbActiveModal,
  NgbModal,
  NgbModalRef
} from "@ng-bootstrap/ng-bootstrap";
import {ActivatedRoute, Router} from "@angular/router";
import {IBoard} from "app/shared/model/board.model";
import {BoardService} from "app/board/board.service";
import {JhiEventManager} from "ng-jhipster";

@Component({
  selector: 'jhi-board-delete-dialog',
  templateUrl: './board-delete-dialog.component.html'
})
export class BoardDeleteDialogComponent {
  board: IBoard;

  constructor(protected boardService: BoardService, public activeModal: NgbActiveModal, protected eventManager: JhiEventManager) {}

  clear() {
    this.activeModal.dismiss('cancel');
  }

  confirmDelete(id: number) {
    this.boardService.delete(id).subscribe(response => {
      this.eventManager.broadcast({
        name: 'boardListModification',
        content: 'Deleted an board'
      });
      this.activeModal.dismiss(true);
    });
  }
}

@Component({
  selector: 'jhi-board-delete-popup',
  template: ''
})
export class BoardDeletePopupComponent implements OnInit, OnDestroy {
  protected ngbModalRef: NgbModalRef;

  constructor(protected activatedRoute: ActivatedRoute, protected router: Router, protected modalService: NgbModal) {}

  ngOnInit() {
    this.activatedRoute.data.subscribe(({ board }) => {
      setTimeout(() => {
        this.ngbModalRef = this.modalService.open(BoardDeleteDialogComponent as Component, { size: 'lg', backdrop: 'static' });
        this.ngbModalRef.componentInstance.board = board;
        this.ngbModalRef.result.then(
          result => {
            this.router.navigate(['/board', { outlets: { popup: null } }]);
            this.ngbModalRef = null;
          },
          reason => {
            this.router.navigate(['/board', { outlets: { popup: null } }]);
            this.ngbModalRef = null;
          }
        );
      }, 0);
    });
  }

  ngOnDestroy(){
    this.ngbModalRef = null;
  }
}

BoardService에 delete를 구현해주어야한다. http delete 통신으로 Resource와 통신한다.

스크린샷 2019-10-25 오전 11.47.39.png

실행시켜보면, 제대로 작동함을 볼 수 있다.

스크린샷 2019-10-25 오후 12.24.58.png

스크린샷 2019-10-25 오후 12.25.08.png

스크린샷 2019-10-25 오후 12.25.15.png

전체 코드는 아래 주소에 있습니다.
https://github.com/KJunseo/jhipster_board_test1

0개의 댓글