1.th:each:循环,<tr th:each="user,userStat:${users}">,userStat是状态变量,有 index,count,size,current,even,odd,first,last等属性,如果没有显示设置状态变量.thymeleaf会默认给个“变量名+Stat"的状态变量。

下面大家看下例子:

  1. <form id="login-form" th:action="@{/addStudent}" th:object="${stuReqBean}" method="POST">
  2.  
  3.   <div class="student" th:each="stuIter,rowStat:${stuReqBean.students}">
  4.  
  5.     <input type="text" class="firstName" value="" th:field="*{students[__${rowStat.index}__].firstName}"></input>
  6.  
  7.     <input type="text" class="school" value="" th:field="*{students[__${rowStat.index}__].school}"></input>
  8.  
  9.   </div>
  10. </form>

上面的例子中通过选择表达式*{}既能将表单绑定到后台的StudentRequestBean中的集合属性students,也能将Servlet上下文中的StudentRequestBean中的List类型的students变量回显,回显时通过th:each进行遍历。

注意1:绑定集合属性元素下标的用法*{students[__${rowStat.index}__].firstName}

注意2:如果List<Student> students为null,页面将无法显示表单,后台必须给students初始化一个值,即:

  1. List<Student > stus = new ArrayList<Student >();
  2.  
  3. stus .add(new Student ());
  4.  
  5. StudentRequestBean.setStudents(stus );

注意3:stuIter代表students的迭代器。

还记得我们之前用过的这个例子吗?

  1. <table>
  2. <tr>
  3. <th>食物名称</th>
  4. <th>食物价格</th>
  5. <th>可现做</th>
  6. <th>食客评价</th>
  7. </tr>
  8. <tr th:each="prod:${prods}">
  9. <td th:text="${prod.name}">醋溜土豆丝</td>
  10. <td th:text="${#numbers.formatDecimal(prod.price,0,2)}">2.41</td>
  11. <td th:text="${prod.isReady}?#{true}:#{false}">yes</td>
  12. <td>
  13. <span th:text=${#lists.size(prod.comments)}>2</span>个评价
  14. <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}"
  15. th:if="${not #lists.isEmpty(prod.comments)}">查看</a>
  16. </td>
  17. </tr>
  18. </table>

**prod:\({prods}**属性值的意思是,迭代\){prods}的每个元素并重复这个模板的这个片段。然后解释一下这两部分分别的意思:

  • ${prods}被称为迭代表达式或迭代变量
  • prod被称为重复变量或迭代值

注意:迭代值只可以用在tr节点上面(包括迭代里边包含的td标签)。

保持迭代状态:当使用th:each的时候,Thymeleaf会提供一个跟着迭代状态的机制:状态变量。状态定义被封装在th:each的属性中。并包含以下数据

  • 获取当前迭代的从0开始的下标,使用index属性
  • 获取当前迭代的从1开始的下标,使用count属性
  • 获取当前迭代元素的总量,使用size属性
  • 获取迭代变量中的迭代值,使用current属性
  • 当前迭代值是奇数还是偶数,使用even/odd的布尔值属性
  • 当前的迭代值是不是第一个元素,使用first布尔值属性
  • 当前迭代值是不是最后一个元素,使用last布尔值属性。

现在将上面的例子稍作修改:

  1. <h1>产品列表</h1>
  2. <table>
  3. <tr>
  4. <th>产品名称</th>
  5. <th>产品价格</th>
  6. <th>有现货</th>
  7. </tr>
  8. <tr th:each="prod,iterStat:${prods}" th:class="${iterStat.odd}?'odd'">
  9. <td th:text="${prod.name}">土豆</td>
  10. <td th:text="${prod.price}">2.41</td>
  11. <td th:text="${prod.inStock}?#{true}:#{false}">yes</td>
  12. </tr>
  13. </table>
  14. <p>
  15. <a href="../home.html" th:href="@{/}">返回首页</a>
  16. </p>

可以看到,状态变量(即iterStat)的定义:将这个变量的名字作为属性写在迭代值之后,用逗号于迭代值隔开。产生了迭代值之后,他的状态值就可以也仅仅可以在th:each包含的代码段中使用。我们再来看一个例子:

  1. <ol>
  2. <li>List循环:
  3. <table border="1">
  4. <tr>
  5. <th>用户名</th>
  6. <th>邮箱</th>
  7. <th>管理员</th>
  8. <th>状态变量:index</th>
  9. <th>状态变量:count</th>
  10. <th>状态变量:size</th>
  11. <th>状态变量:current.userName</th>
  12. <th>状态变量:even</th>
  13. <th>状态变量:odd</th>
  14. <th>状态变量:first</th>
  15. <th>状态变量:last</th>
  16. </tr>
  17. <tr th:each="user,userStat : ${list}">
  18. <td th:text="${user.userName}">Onions</td>
  19. <td th:text="${user.email}">test@test.com.cn</td>
  20. <td th:text="${user.isAdmin}">yes</td>
  21. <th th:text="${userStat.index}">状态变量:index</th>
  22. <th th:text="${userStat.count}">状态变量:count</th>
  23. <th th:text="${userStat.size}">状态变量:size</th>
  24. <th th:text="${userStat.current.userName}">状态变量:current</th>
  25. <th th:text="${userStat.even}">状态变量:even****</th>
  26. <th th:text="${userStat.odd}">状态变量:odd</th>
  27. <th th:text="${userStat.first}">状态变量:first</th>
  28. <th th:text="${userStat.last}">状态变量:last</th>
  29. </tr>
  30. </table>
  31. </li>
  32. <li>Map循环:
  33. <div th:each="mapS:${map}">
  34. <div th:text="${mapS}"></div>
  35. </div>
  36. </li>
  37. <li>数组循环:
  38. <div th:each="arrayS:${arrays}">
  39. <div th:text="${arrayS}"></div>
  40. </div>
  41. </li>
  42. </ol>

现在对each有理解了吗?如果还没有的话,这里还有一个例子:

  1. <div class="item active" th:if="${iterStat.index==0}" th:each="img,iterStat:${pics}">
  2.  
  3.   <img th:src="${img.path}" style="width: 303px;height: 171px;"/>
  4.  
  5. </div>
  6. /*对arrayList对象pics遍历,使用img作为接受参数接收,使用iterStat作为pics下标值,通过iterStat.index得到当前所处下标值;通过th:src="${img.path}"得到对象中图片路径设置图片显示图*/
  7. <tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
  8. <td th:text="${prod.name}">Onions</td>
  9. <td th:text="${prod.price}">2.41</td>
  10. <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
  11. </tr>
  12. /*判断下标是否为奇数,设置tr样式*/

2.th:fragment:我们经常会想让我们的模板包含一些其他模板,比较常见的用途如页眉,页脚,菜单等。为了做到这一点,Thymeleaf需要我们定义一些可用片段,我们能通过th:fragment属性来实现这一点。

例如:

声明模板片段/WEBINF/templates/footer. html

  1. <div th: fragment=" copy" >
  2.  
  3. © 2011 The Good Thymes Virtual Grocery
  4.  
  5. </div>

引入模板片段:

  1. <div th: include=" /templates/footer : : copy" ></div>
  2.  
  3. <div th: replace=" /templates/footer : : copy" ></div>

现在是不是对include replace有有疑问了呢?先看下 th:insert和th:replace的不同点(以及th:include)

  • th:insert是将th:fragment标签的内容纳入宿主标签
  • th:replace是使用th:fragment标签替换宿主标签
  • th:include与th:insert类似,但是他插入的是片段的内容,而不是片段。

还是举个例子吧:

  1. <div th:fragment="copy">
  2. &copy; 网络商店
  3. </div>

导入到两个div标签中:

  1. <body>
  2. ...
  3. <div th:insert="footer :: copy"></div>
  4. <div th:replace="footer :: copy"></div>
  5. <div th:include="footer :: copy"></div>
  6. </body>

执行结果:

  1. <body>
  2. ...
  3. <div>
  4. <footer>
  5. &copy; 网络商店
  6. </footer>
  7. </div>
  8. <footer>
  9. &copy; 网络商店
  10. </footer>
  11. <div>
  12. &copy; 网络商店
  13. </div>
  14. </body>

3.th:attr:设置标签属性,多个属性可以用逗号分隔,比如th:attr="src=@{/image/aa.jpg},title=#{logo}"  (很多大博客上都说这个标签不够优雅,很难看,所以,不常用。)

  1. <form action="subscribe.html" th:attr="action=@{/subscribe}">
  2. <fieldset>
  3. <input type="text" name="email" />
  4. <input type="submit" value="订阅!" th:attr="value=#{subscribe.submit}"/>
  5. </fieldset>
  6. </form>

用法很简单:th:attr将是一个值对应一个属性的表达式,在转换处理后,将会返回如下结果:

  1. <form action="/gtvg/subscribe">
  2. <fieldset>
  3. <input type="text" name="email" />
  4. <input type="submit" value="subscribe me!"/>
  5. </fieldset>
  6. </form>

除了更新了属性值,还可以看到,应用的已经自动将url更新为context前缀的url.如果,我们想在同时更新多个属性呢?xml的规则不允许在一个标签内设置两个同名的属性,所以,可以用逗号来分割th:attr的值,比如:

  1. <img src="../../images/gtvglogo.png"
  2. th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />

将转换为:

  1. <img src="/gtgv/images/gtvglogo.png" title="这里是logo" alt="这里是logo" />

转载:http://www.cnblogs.com/beyrl-blog/p/6634582.html

1.th:each:循环,<tr th:each="user,userStat:${users}">,userStat是状态变量,有 index,count,size,current,even,odd,first,last等属性,如果没有显示设置状态变量.thymeleaf会默认给个“变量名+Stat"的状态变量。

下面大家看下例子:

  1. <form id="login-form" th:action="@{/addStudent}" th:object="${stuReqBean}" method="POST">
  2.  
  3.   <div class="student" th:each="stuIter,rowStat:${stuReqBean.students}">
  4.  
  5.     <input type="text" class="firstName" value="" th:field="*{students[__${rowStat.index}__].firstName}"></input>
  6.  
  7.     <input type="text" class="school" value="" th:field="*{students[__${rowStat.index}__].school}"></input>
  8.  
  9.   </div>
  10. </form>

上面的例子中通过选择表达式*{}既能将表单绑定到后台的StudentRequestBean中的集合属性students,也能将Servlet上下文中的StudentRequestBean中的List类型的students变量回显,回显时通过th:each进行遍历。

注意1:绑定集合属性元素下标的用法*{students[__${rowStat.index}__].firstName}

注意2:如果List<Student> students为null,页面将无法显示表单,后台必须给students初始化一个值,即:

  1. List<Student > stus = new ArrayList<Student >();
  2.  
  3. stus .add(new Student ());
  4.  
  5. StudentRequestBean.setStudents(stus );

注意3:stuIter代表students的迭代器。

还记得我们之前用过的这个例子吗?

  1. <table>
  2. <tr>
  3. <th>食物名称</th>
  4. <th>食物价格</th>
  5. <th>可现做</th>
  6. <th>食客评价</th>
  7. </tr>
  8. <tr th:each="prod:${prods}">
  9. <td th:text="${prod.name}">醋溜土豆丝</td>
  10. <td th:text="${#numbers.formatDecimal(prod.price,0,2)}">2.41</td>
  11. <td th:text="${prod.isReady}?#{true}:#{false}">yes</td>
  12. <td>
  13. <span th:text=${#lists.size(prod.comments)}>2</span>个评价
  14. <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}"
  15. th:if="${not #lists.isEmpty(prod.comments)}">查看</a>
  16. </td>
  17. </tr>
  18. </table>

**prod:\({prods}**属性值的意思是,迭代\){prods}的每个元素并重复这个模板的这个片段。然后解释一下这两部分分别的意思:

  • ${prods}被称为迭代表达式或迭代变量
  • prod被称为重复变量或迭代值

注意:迭代值只可以用在tr节点上面(包括迭代里边包含的td标签)。

保持迭代状态:当使用th:each的时候,Thymeleaf会提供一个跟着迭代状态的机制:状态变量。状态定义被封装在th:each的属性中。并包含以下数据

  • 获取当前迭代的从0开始的下标,使用index属性
  • 获取当前迭代的从1开始的下标,使用count属性
  • 获取当前迭代元素的总量,使用size属性
  • 获取迭代变量中的迭代值,使用current属性
  • 当前迭代值是奇数还是偶数,使用even/odd的布尔值属性
  • 当前的迭代值是不是第一个元素,使用first布尔值属性
  • 当前迭代值是不是最后一个元素,使用last布尔值属性。

现在将上面的例子稍作修改:

  1. <h1>产品列表</h1>
  2. <table>
  3. <tr>
  4. <th>产品名称</th>
  5. <th>产品价格</th>
  6. <th>有现货</th>
  7. </tr>
  8. <tr th:each="prod,iterStat:${prods}" th:class="${iterStat.odd}?'odd'">
  9. <td th:text="${prod.name}">土豆</td>
  10. <td th:text="${prod.price}">2.41</td>
  11. <td th:text="${prod.inStock}?#{true}:#{false}">yes</td>
  12. </tr>
  13. </table>
  14. <p>
  15. <a href="../home.html" th:href="@{/}">返回首页</a>
  16. </p>

可以看到,状态变量(即iterStat)的定义:将这个变量的名字作为属性写在迭代值之后,用逗号于迭代值隔开。产生了迭代值之后,他的状态值就可以也仅仅可以在th:each包含的代码段中使用。我们再来看一个例子:

  1. <ol>
  2. <li>List循环:
  3. <table border="1">
  4. <tr>
  5. <th>用户名</th>
  6. <th>邮箱</th>
  7. <th>管理员</th>
  8. <th>状态变量:index</th>
  9. <th>状态变量:count</th>
  10. <th>状态变量:size</th>
  11. <th>状态变量:current.userName</th>
  12. <th>状态变量:even</th>
  13. <th>状态变量:odd</th>
  14. <th>状态变量:first</th>
  15. <th>状态变量:last</th>
  16. </tr>
  17. <tr th:each="user,userStat : ${list}">
  18. <td th:text="${user.userName}">Onions</td>
  19. <td th:text="${user.email}">test@test.com.cn</td>
  20. <td th:text="${user.isAdmin}">yes</td>
  21. <th th:text="${userStat.index}">状态变量:index</th>
  22. <th th:text="${userStat.count}">状态变量:count</th>
  23. <th th:text="${userStat.size}">状态变量:size</th>
  24. <th th:text="${userStat.current.userName}">状态变量:current</th>
  25. <th th:text="${userStat.even}">状态变量:even****</th>
  26. <th th:text="${userStat.odd}">状态变量:odd</th>
  27. <th th:text="${userStat.first}">状态变量:first</th>
  28. <th th:text="${userStat.last}">状态变量:last</th>
  29. </tr>
  30. </table>
  31. </li>
  32. <li>Map循环:
  33. <div th:each="mapS:${map}">
  34. <div th:text="${mapS}"></div>
  35. </div>
  36. </li>
  37. <li>数组循环:
  38. <div th:each="arrayS:${arrays}">
  39. <div th:text="${arrayS}"></div>
  40. </div>
  41. </li>
  42. </ol>

现在对each有理解了吗?如果还没有的话,这里还有一个例子:

  1. <div class="item active" th:if="${iterStat.index==0}" th:each="img,iterStat:${pics}">
  2.  
  3.   <img th:src="${img.path}" style="width: 303px;height: 171px;"/>
  4.  
  5. </div>
  6. /*对arrayList对象pics遍历,使用img作为接受参数接收,使用iterStat作为pics下标值,通过iterStat.index得到当前所处下标值;通过th:src="${img.path}"得到对象中图片路径设置图片显示图*/
  7. <tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
  8. <td th:text="${prod.name}">Onions</td>
  9. <td th:text="${prod.price}">2.41</td>
  10. <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
  11. </tr>
  12. /*判断下标是否为奇数,设置tr样式*/

2.th:fragment:我们经常会想让我们的模板包含一些其他模板,比较常见的用途如页眉,页脚,菜单等。为了做到这一点,Thymeleaf需要我们定义一些可用片段,我们能通过th:fragment属性来实现这一点。

例如:

声明模板片段/WEBINF/templates/footer. html

  1. <div th: fragment=" copy" >
  2.  
  3. © 2011 The Good Thymes Virtual Grocery
  4.  
  5. </div>

引入模板片段:

  1. <div th: include=" /templates/footer : : copy" ></div>
  2.  
  3. <div th: replace=" /templates/footer : : copy" ></div>

现在是不是对include replace有有疑问了呢?先看下 th:insert和th:replace的不同点(以及th:include)

  • th:insert是将th:fragment标签的内容纳入宿主标签
  • th:replace是使用th:fragment标签替换宿主标签
  • th:include与th:insert类似,但是他插入的是片段的内容,而不是片段。

还是举个例子吧:

  1. <div th:fragment="copy">
  2. &copy; 网络商店
  3. </div>

导入到两个div标签中:

  1. <body>
  2. ...
  3. <div th:insert="footer :: copy"></div>
  4. <div th:replace="footer :: copy"></div>
  5. <div th:include="footer :: copy"></div>
  6. </body>

执行结果:

  1. <body>
  2. ...
  3. <div>
  4. <footer>
  5. &copy; 网络商店
  6. </footer>
  7. </div>
  8. <footer>
  9. &copy; 网络商店
  10. </footer>
  11. <div>
  12. &copy; 网络商店
  13. </div>
  14. </body>

3.th:attr:设置标签属性,多个属性可以用逗号分隔,比如th:attr="src=@{/image/aa.jpg},title=#{logo}"  (很多大博客上都说这个标签不够优雅,很难看,所以,不常用。)

  1. <form action="subscribe.html" th:attr="action=@{/subscribe}">
  2. <fieldset>
  3. <input type="text" name="email" />
  4. <input type="submit" value="订阅!" th:attr="value=#{subscribe.submit}"/>
  5. </fieldset>
  6. </form>

用法很简单:th:attr将是一个值对应一个属性的表达式,在转换处理后,将会返回如下结果:

  1. <form action="/gtvg/subscribe">
  2. <fieldset>
  3. <input type="text" name="email" />
  4. <input type="submit" value="subscribe me!"/>
  5. </fieldset>
  6. </form>

除了更新了属性值,还可以看到,应用的已经自动将url更新为context前缀的url.如果,我们想在同时更新多个属性呢?xml的规则不允许在一个标签内设置两个同名的属性,所以,可以用逗号来分割th:attr的值,比如:

  1. <img src="../../images/gtvglogo.png"
  2. th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />

将转换为:

  1. <img src="/gtgv/images/gtvglogo.png" title="这里是logo" alt="这里是logo" />

初步认识thymeleaf:简单表达式和标签(二)的更多相关文章

  1. 初步认识thymeleaf:简单表达式和标签(一)

    初步认识Thymeleaf:简单表达式和标签.(一)   本文只适用于不会Java对HTML语言有基础的程序员们,是浏览了各大博客后收集整理,重新编辑的一篇文章,希望能对大家有所帮助.最后本文如果有哪 ...

  2. 初步认识Thymeleaf:简单表达式和标签。(一)

    本文只适用于不会Java对HTML语言有基础的程序员们,是浏览了各大博客后收集整理,重新编辑的一篇文章,希望能对大家有所帮助. 对于Thymeleaf,网上特别官方的解释无非就是:网站或者独立应用程序 ...

  3. 认识Thymeleaf:简单表达式和标签 基础信息

    转载:https://www.cnblogs.com/beyrl-blog/p/6633182.html 本文只适用于不会Java对HTML语言有基础的程序员们,是浏览了各大博客后收集整理,重新编辑的 ...

  4. 初步认识Thymeleaf:简单表达式和标签。(二)

    本篇文章是对上篇文章中Thymeleaf标签的补充. 1.th:each:循环,<tr th:each="user,userStat:${users}">,userSt ...

  5. (二)Thymeleaf标准表达式之——简单表达式

    2. 标准表达式(Standard Expression Syntax) 标准表达式包含以下几个方面: 简单表达式: 变量表达式: ${...} 选择变量表达式: *{...} 消息表达式: #{.. ...

  6. Thymeleaf 页面表达式基础

    转自:http://www.cnblogs.com/vinphy/p/4674247.html#undefined (一)Thymeleaf 是个什么?      简单说, Thymeleaf 是一个 ...

  7. Python 简单入门指北(二)

    Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值.总而言之,函数和普通变量 ...

  8. keras实现简单性别识别(二分类问题)

    keras实现简单性别识别(二分类问题) 第一步:准备好需要的库 tensorflow  1.4.0 h5py 2.7.0 hdf5 1.8.15.1 Keras     2.0.8 opencv-p ...

  9. 基于Java的简易表达式解析工具(二)

    之前简单的介绍了这个基于Java表达式解析工具,现在把代码分享给大家,希望帮助到有需要的人们,这个分享代码中依赖了一些其他的类,这些类大家可以根据自己的情况进行导入,无非就是写字符串处理工具类,日期处 ...

随机推荐

  1. erMaster插件

    需求: 在做开源项目时,了解基本业务后.试图从数据库表设计来分析项目.通过visio时绘制操作繁琐,另外不能与数据库连动.于是想找一款快速绘制er图,并且能够和数据库连动的软件工具. eclipse插 ...

  2. 1051. Pop Sequence (25)

    题目如下: Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, ..., N ...

  3. hashmap简单实例(个人使用经验)

    一.HashMap<int,String>是错误的:因为int是基本类型,而key和value要求是对象,所以要用Integer而不是int.HashMap<String,Objec ...

  4. iOS中 Animation 动画大全 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! iOS开发者交流QQ群: 446310206 1.iOS中我们能看到的控件都是UIView的子类,比如UIButt ...

  5. 多进程log4cxx区分日志

    多进程log4cxx区分日志 (金庆的专栏) 网游客户端一般会多开,多个进程会写同一个日志文件.log4cxx看来会对文件加锁,防止多进程写同一文件写乱,截止目前还没发现错乱的日志. log4cxx有 ...

  6. 看到个有趣的方法批量下载rtf模板

    一般想要批量下载rtf模板我们都是用fndload来实现或者 perl download.pl来实现,今天看到一个比较有趣的方法 Hi, Blob column 'template file data ...

  7. 海量数据挖掘MMDS week3:社交网络之社区检测:高级技巧

    http://blog.csdn.net/pipisorry/article/details/49052255 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...

  8. Jquery之Bind方法参数传递与接收的三种方法

     方法一. function GetCode(event) { alert(event.data.foo); } $(document).ready(function() { $("#s ...

  9. Android学习笔记:对Android应用进行单元测试

     第一步:在AndroidManifest.xml中加入如下两段代码: <manifest xmlns:android="http://schemas.android.com/ap ...

  10. 使用LogKit进行日志操作

    1.      概述 任何一个系统中,日志都是不可缺少的,现在Apache提供了两套日志工具,一个就是Log4j,另一个是本文要给出例子的LogKit. Log4j和LogKit有很多相似的地方.比如 ...