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=1
regions
또한 count=1
이므로, th:field="*{regions}
가 id=regions1
을 생성하고 count에 1을 추가한다. //count = 2
label
의 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
를 반환한다!