for에 있는 id 값을 field가 똑같이 만들어주기도 함
근데 label의 for 값이 없는 경우, field로 인해 생성되는 id값은 name + 1 이었다.
뭐가 먼저랄게 없는 것 같다.
<div>
<div>등록 지역</div>
<div th:each="region : ${regions}" class="form-check form-check-inline">
<input type="checkbox" th:field="*{regions}" th:value="${region.key}" class="form-check-input">
<label th:for="${#ids.prev('regions')}"
th:text="${region.value}" class="form-check-label">서울</label>
</div>
</div>
field가 name=regions, id=regions1, 2, 3...과 같이 임의의 id를 부여함label안의 th:for=${#ids.prev('regions')}가 field의 id값을 참조함위의 메커니즘으로 checkbox의 id값과 label의 id값이 동일해지는 듯 하다.
하지만, 솔직히 '#ids.prev('regions')라는 녀석의 메커니즘이 너무 이해가 가지 않았다.
얘는 어떻게 field가 생성한 id값을 참조하는거야?
public String prev(final Object id) {
Validate.notNull(id, "ID cannot be null");
final String str = id.toString();
return str + this.context.getIdentifierSequences().getPreviousIDSeq(str);
}
타임리프가 제공하는 Ids라는 class의 prev() 메서드이다.
메서드의 특징은 다음과 같다.
id값을 Object로 받는다.id값을 toString()을 통해 String타입으로 변환한다.String타입의 id값 뒤에 수상한 것을 붙여준다.수상한 this.context.getIdentifierSequences().getPreviousIDseq(str);의 정체?
ITemplateContext 타입인 context
ITemplateContext는 하나의 interface이다.prev()메서드가 사용하는 메서드는 getIdentifierSequence() 메서드이다.IdentifierSequences를 반환한다getIdentifierSequences()로 IdentifierSequences를 얻는다.
해당 클래스에는 Map<String, Integer> idCounts 변수와 getPreviousIDseq()이라는 메서드가 있다.
public Integer getPreviousIDSeq(final String id) {
Validate.notNull(id, "ID cannot be null");
final Integer count = this.idCounts.get(id);
if (count == null) {
throw new TemplateProcessingException(
"Cannot obtain previous ID count for ID \"" + id + "\"");
}
return Integer.valueOf(count.intValue() - 1);
}
Map<String, Integer> idCounts
id 값마다 카운트 횟수가 Map형태로 저장되는 듯 하다.id 값이란, 위 예제에서의 regions이다.th:each문을 돌 때 마다 id(regions)가 몇 회나 카운트되었는지 기록되는 듯 하다.count는 1부터 시작한다.getPreviousIDseq(String id)
String 타입의 id값을 파라미터로 받는다.id값은 가장 마지막에 count된 ID값이다.count를 반환한다.위 예제에서의 id값의 count
count는 1부터 시작하므로 1일 것이다. //count=1regions또한 count=1이므로, th:field="*{regions}가 id=regions1을 생성하고 count에 1을 추가한다. //count = 2label의 th:for=${#ids.prev('regions')}가 id값을 만들기 위해 메서드를 수행한다.getPreviousIDseq(String id)에 의해 count - 1값이 반환되어 1을 반환한다. //count = 2 였으므로, 해당 메서드에 의해 1이 반환된다.1을 id값인 'regions'뒤에 붙여 'regions1'을 반환한다.위의 메커니즘이라면, (filed로 생성된 id가 'regions1'일 때)
id.next()는 regions2를 반환한다.id값과 labels의 id값이 달라진다.고찰 :
id.prev()는field가 생성한id를 참조하는게 아닌,count횟수를 참조하여 새로id를 만드는 것 같다. 서로 같기 때문에 참조같아 보이는 것 같은...
결론 :
id.prev()는th:field로 생성된id와 동일한id를 반환한다!