hero 삭제
사진 보기를 추가한 hero 목록리스트를 만든다. 사용자 사이트에서 한것과 동일하게 코드를 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
export class ManageHeroComponent implements OnInit { heroes: Hero[]; constructor(private heroService: HeroService) { } ngOnInit() { this.heroService.getHeroes() .subscribe(data => { this.heroes = data; console.log(this.heroes); }); } } |
여기서 HeroService 를 주입하였다. HeroService는 root 태그에서 등록되었기 때문에 모든 모듈에서 사용가능하다.
뷰에서는 사진을 추가해서 목록보기를 만든다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<h2>My Heroes</h2> <ul> <li class="d-flex m-1" *ngFor="let hero of heroes"> <span class="rounded-left p-2 bg-primary text-light">{{hero.hero_id}}</span> <div class="rounded-right p-2 bg-light text-dark w-50">{{hero.name}}</div> </li> </ul> <table class="table table-striped"> <tr> <th style="width: 20%;">사진</th> <th style="width: 60%;">이름</th> <th style="width: 20%;">수정</th> </tr> <tr *ngFor="let hero of heroes"> <td> <img [src]="hero.photo" style="width: 5rem;" *ngIf="hero.photo"> </td> <td class="flex-fill">{{hero.name}}</td> <td> <button class="btn btn-info btn-sm">수정</button> <button class="btn btn-danger btn-sm ml-2">삭제</button> </td> </tr> </table> |
모달창 띄우기
삭제 버튼을 누르면 삭제를 하는데 confirm창 대신 modal 창을 띄워서 물어보도록 변경해보자.
admin모듈에 부트스트랩 모듈을 추가한다.
1 |
NgbModule, |
root 모듈에서는 NgbModule.forRoot()로 다른 모듈에서는 간단히 NgbModule 를 추가하면 된다.
모달창 컴포넌트를 생성한다.
1 |
ng g component admin/manage-hero/manage-dialog |
그리고 반드시 모듈에 entryComponents에 등록하는것을 잊지말자.
1 |
entryComponents: [ManageDialogComponent] |
모달창에서는 부모에게서 넘어온 name 변수와 뷰에서 사용할 activeModal 서비스를 주입받는다.
1 2 3 4 5 6 7 8 9 |
export class ManageDialogComponent implements OnInit { @Input() name; constructor(public activeModal: NgbActiveModal) {} ngOnInit() { } } |
모달창 뷰는 modal-header, modal-body, modal-footer 클래스로 구성한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="modal-header"> <h4 class="modal-title">Hi there!</h4> <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>{{name}}을(를) 삭제하시겠습니까?</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-success" (click)="activeModal.close('Close click')">확인</button> <button type="button" class="btn btn-warning" (click)="activeModal.close('Close click')">취소</button> </div> |
이제 부모창에서 호출하는 부분을 보자
부모 뷰에 클릭 이벤트를 추가한다.
1 2 3 4 |
<td> <button class="btn btn-info btn-sm">수정</button> <button class="btn btn-danger btn-sm ml-2" (click)="confirmDelete(hero)">삭제</button> </td> |
생성자에서 NgbModal 서비스를 주입받고 이를 이용해서 레퍼런스를 얻은 다음에 name 변수를 넘겨준다.
1 2 3 4 5 6 |
constructor(private heroService: HeroService, private modalService: NgbModal) { } confirmDelete(hero: Hero) { const dialogRef = this.modalService.open(ManageDialogComponent); dialogRef.componentInstance.name = hero.name; } |
삭제로직
자식창에서 확인 혹은 취소를 눌렀을때 그 결과를 가져오는 부분을 추가한다.
확인이나 취소를 눌러서 그 결과를 확인해보면 close() 함수 안에 넣은 부분이 리턴된다는것을 알수 있다.
1 2 |
dialogRef.result .then(data => console.log(data)); |
자식창 뷰에서 확인을 누르면 true를 취소는 false를 리턴하도록 수정하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="modal-header"> <h4 class="modal-title">Hi there!</h4> <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss(false)"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>{{name}}을(를) 삭제하시겠습니까?</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-success" (click)="activeModal.close(true)">확인</button> <button type="button" class="btn btn-warning" (click)="activeModal.close(false)">취소</button> </div> |
이제 부모창에서 자식창에서 넘어온 데이터가 true이면 실제로 데이터를 삭제한다.
먼저 서비스에 삭제 api를 추가한다.
1 2 3 |
removeHero(hero_id: number): Observable<ResultVo> { return this.http.delete<ResultVo>(`${environment.HOST}/api/hero?hero_id=${hero_id}`); } |
컴포넌트에서 호출하고 array에서 해당 인덱스를 찾아서 삭제한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
confirmDelete(hero: Hero) { const dialogRef = this.modalService.open(ManageDialogComponent); dialogRef.componentInstance.name = hero.name; dialogRef.result .then(data => { console.log(data); if (data) { this.adminService.removeHero(hero.hero_id) .subscribe(body => { console.log(body); const index = this.heroes.findIndex(item => item.hero_id === hero.hero_id ? true : false); this.heroes.splice(index, 1); }); } }); } |