[Spring Boot] aLog Project - 수정, 삭제 페이지 만들기

김광현·2023년 9월 8일
0

Project - aLog

목록 보기
8/12
post-thumbnail

[Spring Boot] aLog Project - 조회 페이지 만들기 에 이어서 수정, 삭제 페이지를 구현합니다. 🏆


💻 수정

posts-update.mustache

게시글 수정 화면 머스테치 파일을 생성합니다.

{{>layout/header}}

<h1>게시글 수정</h1>

<div class="col-md-12">
    <div class="col-md-4">
        <form>
            <div class="form-group">
                <label for="title">글 번호</label>
                <input type="text" class="form-control" id="id" value="{{post.id}}" readonly>
            </div>
            <div class="form-group">
                <label for="title">제목</label>
                <input type="text" class="form-control" id="title" value="{{post.title}}">
            </div>
            <div class="form-group">
                <label for="author"> 작성자 </label>
                <input type="text" class="form-control" id="author" value="{{post.author}}" readonly>
            </div>
            <div class="form-group">
                <label for="content"> 내용 </label>
                <textarea class="form-control" id="content">{{post.content}}</textarea>
            </div>
        </form>
        <a href="/" role="button" class="btn btn-secondary">취소</a>
        <button type="button" class="btn btn-primary" id="btn-update">수정 완료</button>
    </div>
</div>

{{>layout/footer}}

📁 코드 설명

1. {{post.id}}
	- 머스테치는 객체의 필드 접근 시 점(Dot)으로 구분합니다.
    
2. readonly
	- Input 태그에 읽기 기능만 허용하는 속성입니다.

index.js

btn-update 버튼을 클릭하면 update 기능을 호출할 수 있게 index.js 파일에도 update function을 추가합니다.

var main = {
    init : function () {
        var _this = this;
        ...
        $('#btn-update').on('click', function () {
            _this.update();
        });
    },
    ...
    update : function () {
        var date = {
            title: $('#title').val(),
            content: $('#content').val()
        };

        var id = $('#id').val();

        $.ajax({
            type: 'PUT',
            url: '/api/v1/posts/'+id,
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify(data)
        }).done(function() {
            alert('글이 수정되었습니다.');
            window.location.href = '/';
        }).fail(function (error) {
            alert(JSON.stringify(error));
        });
    }
};

main.init();

📁 코드 설명

1. $('#btn-update').on('click')
	- btn-update란 id를 가진 HTML 엘리먼트에 click 이벤트가 발생할 때 update function을 실행하도록 이벤트를 등록합니다.
    
2. update : function()
	- 신규로 추가될 update function입니다.
    
3. type: 'PUT'
	- 여러 HTTP Method 중 PUT 메소드를 선택합니다.
    - PostsApiController에 있는 API에서 이미 @PutMapping으로 선언했기 때문에 PUT을 사용해야 합니다. 참고로 이는 rEST 규약에 맞게 설정된 것입니다.
    - REST에서 CRUD는 다음과 같이 HTTP Method에 매핑됩니다.
    	생성 (Create) - POST
        읽기 (Read) - GET
        수정 (Update) - PUT
        삭제 (Delete) - DELETE
        
4. url: '/api/v1/posts/'+id
	- 어느 게시글에 수정할지 URL Path로 구분하기 위해 Path에 id를 추가합니다.

index.mustache

전체 목록에서 수정 페이지로 이동할 수 있게 페이지 이동 기능을 추가합니다.

...
<tbody id="tbody">
{{#posts}}
	<tr>
		<td>{{id}}</td>
		<td><a href="/posts/update/{{id}}">{{title}}</a></td>
		<td>{{author}}</td>
		<td>{{modifiedDate}}</td>
	</tr>
{{/posts}}
</tbody>
...

📁 코드 설명

1. <a href="/posts/update/{{id}}"></a>
	- 타이틀(title)에 a tag를 추가합니다.
    - 타이틀을 클릭하면 해당 게시글의 수정 화면으로 이동합니다.

IndexConroller.java

IndexConroller.java에 메소드를 추가합니다.

...
@GetMapping("/posts/update/{id}")
    public String postsUpdate(@PathVariable Long id, Model model) {
        PostsResponseDto dto = postsService.findById(id);
        model.addAttribute("post", dto);
        
        return "posts-update";
    }
}


💻 삭제

posts-update.mustache

삭제 버튼은 본문을 확인하고 진행해야 하므로, 수정 화면에 추가합니다.

...
<div class="col-md-12">
    <div class="col-md-4">
        ...
        <a href="/" role="button" class="btn btn-secondary">취소</a>
        <button type="button" class="btn btn-primary" id="btn-update">수정 완료</button>
        <button type="button" class="btn btn-danger" id="btn-delete">삭제</button>
    </div>
</div>

{{>layout/footer}}

📁 코드 설명

1. btn-delte
	- 삭제 버튼을 수정 완료 버튼 옆에 추가합니다.
    - 해당 버튼 클릭 시 JS에서 이벤트를 수신할 에정입니다.

Index.js

삭제 이벤트를 진행할 JS 코드를 추가합니다.

	...
	$('#btn-delete').on('click', function () {
            _this.delete();
        });
    },
	...
	delete : function () {
        var id = $('#id').val();
    
        $.ajax({
            type: 'DELETE',
            url: '/api/v1/posts/'+id,
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
        }).done(function() {
            alert('글이 삭제되었습니다.');
            window.location.href = '/';
        }).fail(function (error) {
            alert(JSON.stringify(error));
        });
    }
};

main.init();

PostsService.java

서비스 메소드에 삭제 API를 작성합니다.

	...
	@Transactional
    public void delete (Long id) {
        Posts posts = postsRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id=" + id));
        
        postsRepository.delete(posts);
    }
    ...
}

📁 코드 설명

1. postsRepository.delete(posts)
	- JpaRepository에서 이미 delete 메소드를 지원하고 있으니 이를 활용합니다.
    - Entity를 파라미터로 삭제할 수도 있고, deleteById 메소드를 이용하면 id로 삭제할 수도 있습니다.
    - 존재하는 Posts인지 확인을 위해 Entity 조회 후 그대로 삭제합니다.

PostsApiController.java

서비스에서 만든 delete 메소드를 컨트롤러가 사용하도록 코드를 추가합니다.

...
@DeleteMapping("/api/v1/posts/{id}")
    public Long delete(@PathVariable Long id) {
        postsService.delete(id);
        return id;
    }
}


✅ 추가 작성

index.js 파일에 변수 선언 방식을 var에서 let으로 변경했습니다.

let main = {
    init : function () {
        let _this = this;
      	...
}

var 경우 기존에 선언해둔 변수의 존재를 잊고 재선언 하는 경우 문제가 발생할 수 있습니다.
따라서 ES6부터 추가된 변수 선언 방식인 let 권장되어 변경했습니다.


✔ 머스테치를 이용하여 게시글 수정, 삭제 페이지를 구현해봤습니다.

profile
🅸nterest 🆂olving 🆃horough 🅹udgment

0개의 댓글