<select name="resultStatus" class="form-control form-select size11" id="result_status">
<option value="WAITING" th:selected="${Result?.reportResultStatus?.name == 'WAITING'}">처리 접수</option>
<option value="IN_PROGRESS" th:selected="${Result?.reportResultStatus?.name == 'IN_PROGRESS'}">처리중</option>
<option value="INACTIVE" th:selected="${Result?.reportResultStatus?.name == 'INACTIVE'}">비활성화</option>
<option value="REJECT" th:selected="${Result?.reportResultStatus?.name == 'REJECT'}">반려</option>
</select>
상태에 관련된 변수값을 enum으로 관리하는 것을 거의 필수라고 할 수 있다. 타임리프를 사용하다보면 option 태그안에 enum 값을 매핑해 보여줄 필요가 생기는데 보통 위처럼 작업을 했었다.
Result 라는 객체 안에 있는 enum 값은 아래와 같다.
enum class ReportResultStatus(val value: String) {
WAITING("신고 접수"),
IN_PROGRESS("처리중"),
INACTIVE("비활성화"),
REJECT("반려"),
}
그러나 enum의 name, value 값은 언제나 변경 될 가능성이 있으므로 view 단에서 하드코딩해서 다루는 것은 적절하지 않다고 생각이 들었다.
그래서 enum 값을 option 태그에 매핑하는 fragment를 생성하기로 했다.
<!-- /fragments/enumSelect.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="enumOptions (enumClassName, selectedValue)">
<option th:each="status : ${T(enumClassName).values()}"
th:value="${status.name()}"
th:text="${status.value}"
th:selected="${status.name() == selectedValue?.name}">
</option>
</div>
</body>
</html>
<select name="reportResultStatus" class="form-control form-select size11" id="result_status">
<div th:replace="layout/enum/enum_option :: enumOptions('ReportResultStatus', ${Result?.reportResultStatus})"></div>
</select>
여기서 T 연산자는 정적 메소드나 인스턴스에 접근하기 위한 스프링 표현법이다. 문제는 T 연산자를 통한 동적 문자열 삽입이나 fragment를 통한 다른 컨텍스에서의 접근이 안된다.. 그렇다고 매번 view단에서 저 코드를 반복 생성 하는 것도 원하지 않았다. 따라서 아래 방법처럼 구현을 했다.
<!-- /fragments/enumSelect.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="enumOptions(enumClassName, selectedValue)">
<!-- enumClassName에 따라 적절한 enum을 선택 -->
<div th:with="enumValues=
${enumClassName == 'ReportResultStatus' ? T(com.minggu.enums.ReportResultStatus).values() :
(enumClassName == 'AnotherEnumClass' ? T(com.minggu.enums.AnotherEnumClass).values() :
null)}">
<!-- 공통 처리 부분 -->
<option th:each="status : ${enumValues}"
th:value="${status.name()}"
th:text="${status.value}"
th:selected="${status.name() == selectedValue?.name}">
</option>
</div>
</div>
</body>
</html>
<div th:replace="layout/enum/enum_option :: enumOptions('ReportResultStatus', ${ReportResult?.reportResultStatus})"></div>
매번 enum 값을 명시해줘야 하긴 하지만 그나마 이렇게 작성하는게 중복코드를 줄이고 enum 값의 value, name이 변경되어도 안전하다.
<참고>
'Back-end' 카테고리의 다른 글
[gRPC] Armeria + gRPC 띄워보기 (7) | 2024.10.07 |
---|---|
[gRPC] gRPC란 (3) | 2024.10.02 |
[Redis] Cache 전략 (0) | 2024.07.29 |
Redis의 분산락 사용에 대해서 (0) | 2024.07.19 |
[C#] using 구문 (1) | 2022.09.08 |