-->
728x90
<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이 변경되어도 안전하다.

 

 

<참고>

https://www.baeldung.com/thymeleaf-enums

반응형

+ Recent posts