Thymeleaf
双列表同步循环问题
问题复现:
现有一个区块需要同时遍历两个列表进行取值,分别为 question
和 falg
。
html示例代码如下所示:
<form id="myform" th:action="@{/submit}" method="post">
<ol class="fields">
<li th:each="question : ${questionList}" th:each="falg : ${falgList}">
<label th:text="${question.name}">示例问题1</label>
<input th:if="${question.getOptList()==null}" th:name="*{falg.r1}" type="text" required/>
<select title="请选择其中一项..." th:if="${question.getOptList()!=null}" th:each="opt : ${question.getOptList()}" th:name="*{falg.r1}">
<option value="" disabled selected>--请选择--</option>
<option th:text="${opt.oname}" th:value="*{opt.oname}" >答案1</option>
</select>
</li>
</ol>
<button title="提交" class="fs-submit" type="submit">提交</button>
</form>
此时运行报错:
Attribute "th:each" appears more than once in element
意思是一个元素中,循环遍历th:each
不能超过一个。
但如果我们选择把第二个循环放在里面用span标签,改动后代码:
<form id="myform" th:action="@{/submit}" method="post">
<ol class="fields">
<li th:each="question : ${questionList}">
<span th:each="falg : ${falgList}">
<label th:text="${question.name}">示例问题1</label>
<input th:if="${question.getOptList()==null}" th:name="*{falg.r1}" type="text" required/>
<select title="请选择其中一项..." th:if="${question.getOptList()!=null}" th:each="opt : ${question.getOptList()}" th:name="*{falg.r1}">
<option value="" disabled selected>--请选择--</option>
<option th:text="${opt.oname}" th:value="*{opt.oname}" >答案1</option>
</select>
</span>
</li>
</ol>
<button title="提交" class="fs-submit" type="submit">提交</button>
</form>
这样控制台确实不报错了,但是页面会渲染两次循环内的内容,这并不是我们想要的。
那我们如何解决这个问题呢?
问题解决:
答案就是用Map
替换掉List
装载数据。
我们知道,Map
的属性是一对键值对,我们用key
来装载question
数据,用value
来装载flag
数据,这样循环就只需要一个就可以了。
特别注意
:虽然Map
集合的Value
值可重复,但是,Map
集合的Key
键不允许重复,否则新数据Value
值会覆盖掉key
键对应的原来的Value
值!所以,Key
键装载的数据务必没有重复,这非常重要!!!否则会导致数据缺省。
Map
集合Key
值重复测试代码:
void test(){
Map<String,String> map = new HashMap<>();
map.put("a","1");
System.out.println("第一次添加数据:"+map);
map.put("a","2");
System.out.println("Key值相同,第二次添加数据:"+map);
}
控制台输出:
第一次添加数据:{a=1}
Key值相同,第二次添加数据:{a=2}
改动后示例代码:
<form id="myform" th:action="@{/submit}" method="post">
<ol class="fields">
<li th:each="map : ${maps}" >
<label th:text="${map.getKey().qname}">你叫什么名字?</label>
<input th:if="${map.getKey().getOptList()==null}" th:name="*{map.getValue().r1}" type="text" required/>
<select title="请选择其中一项..." th:if="${map.getKey().getOptList()!=null}" th:each="opt : ${map.getKey().getOptList()}" th:name="*{map.getValue().r1}">
<option value="" disabled selected>--请选择--</option>
<option th:text="${opt.oname}" th:value="*{opt.oname}" >#588c75</option>
</select>
</li>
</ol>
<button title="提交" class="fs-submit" type="submit">提交</button>
</form>
后端Controller
内就把两个List
列表内的属性取出来加到Map
集合中,然后再将Map
集合添加到Model
共享域中就可以了!
觉得有帮助的话,不妨点个赞和收藏,加个关注吧!
以上为个人浅薄理解,如有更好的方法或者有需要改进的地方,欢迎评论区指正。