1. 고민

가계부 프로젝트에서 핵심은 지출내역 저장/수정/삭제라고 생각하는데, 수정 화면을 만들 때 고민이 많이 되었다. 가장 고민이 되었던 부분은 수정 페이지로 넘어갔을 때 해당 리소스의 데이터를 어떻게 가져올 것인지였다. 등록 화면은 기존 데이터가 있을 필요없이 그냥 새로운 페이지를 만들면 되는데, 수정 화면은 기존의 리소스 데이터를 가져와서 보여준 뒤 사용자가 변경한 것을 저장하는 방식으로 진행을 해야했다. 

 

진행하면서 가장 고민이 되었던 부분은 기존의 리소스 데이터를 어떤 로직으로 가져와서 보여줄 것인지였다. 처음에는 화면 로딩 시 ajax로 데이터를 가져와서 반영하려고 했으나 아직 미숙해서 그런지 잘되지 않았다. 그래서 이전에 배웠던 Thymeleaf의 th:value 문법Controller에서 Model 객체로 수정하려는 리소스의 데이터를 담아서 화면에 넘겨주는 방식을 선택했다.

 

2. 순서

진행 순서는 다음과 같다.

 

1. '수정' 버튼 클릭

2. 수정화면으로 이동 + 클라이언트는 url로 리소스(지출내역) id를 서버로 전달

3. 서버는 받은 id로 리소스 정보를 db에서 가져와 Controller 단에서 Model에 담아서 전달

4. model에 있는 정보를 화면에서 보여주기

 

2-1. '수정' 버튼 클릭

// 수정 버튼 클릭시 modifyDailyPayment(this.id) 호출
// 여기서 this.id는 리소스의 id가 되게 설정했다
`<button class="btn btn-success btn-payment" id="`+ paymentId + `" onclick="modifyDailyPayments(this.id);">수정</button></li> `;

 

2-2. 수정화면으로 이동 + 클라이언트는 url로 리소스(지출내역) id를 서버로 전달

// 해당 리소스의 수정 화면으로 이동
function modifyDailyPayments(paymentId) {
  location.replace("http://localhost:8080/expenditure/" + paymentId);
}

 

2-3. 서버는 받은 id로 리소스 정보를 db에서 가져와 Controller 단에서 Model에 담아서 전달

@Controller
@RequiredArgsConstructor
public class AccountBookController {    
    
    @GetMapping("/expenditure/{paymentId}")
    public String modifyExpenditure(@PathVariable long paymentId, Model model) {
        GetDailyPaymentsResponseDto payment = dailyPaymentsService
                .getDailyPayment(paymentId);
                
        model.addAttribute("payment", payment);
        return "edit-expenditure";
    }
}

dailyPaymentsService에서 id로 리소스를 식별해 정보를 GetDailyPaymentsReponseDto 객체에 저장한 뒤, Model을 통해 "payment"라는 이름으로 해당 정보를 view로 넘겨준다.

 

- GetDailyPaymentsResponseDto.class

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GetDailyPaymentsResponseDto {

    private long dailyPaymentId;
    private Integer paidAmount;
    private String payLocation;
    private String methodOfPayment;
    private Long categoryId;
    private String categoryName;
    private String memo;
    private String date;
    
    public static GetDailyPaymentsResponseDto of(DailyPayments dailyPayments, String categoryName) {
        return GetDailyPaymentsResponseDto
                .builder()
                .dailyPaymentId(dailyPayments.getId())
                .paidAmount(dailyPayments.getPaidAmount())
                .payLocation(dailyPayments.getPayLocation())
                .methodOfPayment(dailyPayments.getMethodOfPayment())
                .categoryId(dailyPayments.getCategoryId())
                .categoryName(categoryName)
                .memo(dailyPayments.getMemo())
                .date(dailyPayments.getDate())
                .build();
    }
}

 

- model.addAttribute()

model.addAttribute("payment", payment);

 

 

필요한 정보를 view에 모두 보냈으면, 수정화면으로 이동하기 위해 "edit-expenditure" 문자열을 반환하면 된다.

 

 

2-4. model에 있는 정보를 화면에서 보여주기

위의 과정을 거치면 기존에 저장되어있던 지출 정보를 수정 화면에서 확인할 수 있다.

아직 드롭박스에 반영하는 법은 잘 모르겠다. 추후 적용 예정!

 

코드

위에서 서버에서 가져온 지출내역을 payment라는 이름으로 view에 넘겼다. 그렇기에 thymeleaf 문법을 이용해 payment의 정보를 적재적소에 위치시켜보자.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="layout/default_layout">
<th:block layout:fragment="content">

    <div id="top" class="container text-center">
        <div class="row">
            <h3>지출 수정하기</h3>
        </div>
    </div>

    <div id="middle1" class="container text-center" style="padding-top:50px;">
        <div class="row">
            <div class="col-6">금액<input id="paid-amount" th:value="${payment.paidAmount}"></div>
            <div class="col-6">
                카테고리
                <button class="btn btn-light" type="button" th:text="${payment.categoryName}" id="category-radio" data-bs-toggle="modal" data-bs-target="#categoryModal" onclick="getCategoryList();" ></button>
            </div>
        </div>
    </div>

    <div id="middle2" class="container text-center" style="padding-top:50px;">
        <div class="row">
            <div class="col-6">거래처<input id="pay-location" th:value="${payment.payLocation}"></div>
            <div class="col-6">결제 수단<input id="method-payment" th:value="${payment.methodOfPayment}"></div>
        </div>
    </div>

    <div id="middle3" class="container text-center" style="padding-top:50px;">
        <div class="row">
            <div class="col-6">메모<input id="memo" th:value="${payment.memo}"></div>
            <div class="col-6">날짜
                <select id="date-select" class="form-select" onclick="getDate();" th:text="${payment.date}"></select>
            </div>
        </div>
    </div>
    
    ...
    
<th:block>
</html>

 

 

기본적인 thymeleaf 문법은 아래 th:value=..  형식을 따르면 된다.

<input id="paid-amount" th:value="${payment.paidAmount}">

 

 

2-5. 수정 완료

이제 원하는 만큼 정보를 변경한 뒤 아래 "수정하기" 버튼을 클릭하면 수정 api를 전송하면서 수정이 완료된다.

+ Recent posts