zoukankan      html  css  js  c++  java
  • 初步认识thymeleaf:简单表达式和标签(二)

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

    下面大家看下例子:

     

    复制代码
    <form id="login-form" th:action="@{/addStudent}" th:object="${stuReqBean}" method="POST">
    
      <div class="student" th:each="stuIter,rowStat:${stuReqBean.students}">
    
        <input type="text" class="firstName" value="" th:field="*{students[__${rowStat.index}__].firstName}"></input>
    
        <input type="text" class="school" value="" th:field="*{students[__${rowStat.index}__].school}"></input>
    
      </div>
    </form>
    复制代码

     

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

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

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

    List<Student > stus = new ArrayList<Student >();
    
    stus .add(new Student ());
    
    StudentRequestBean.setStudents(stus );

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

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

    复制代码
    <table>
        <tr>
            <th>食物名称</th>
            <th>食物价格</th>
            <th>可现做</th>
            <th>食客评价</th>
        </tr>
        <tr th:each="prod:${prods}">
            <td th:text="${prod.name}">醋溜土豆丝</td>
            <td th:text="${#numbers.formatDecimal(prod.price,0,2)}">2.41</td>
            <td th:text="${prod.isReady}?#{true}:#{false}">yes</td>
            <td>
                <span th:text=${#lists.size(prod.comments)}>2</span>个评价
                <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}"
                th:if="${not #lists.isEmpty(prod.comments)}">查看</a>
            </td>
        </tr>
    </table>
    复制代码

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

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

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

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

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

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

    复制代码
    <h1>产品列表</h1>
    <table>
        <tr>
            <th>产品名称</th>
            <th>产品价格</th>
            <th>有现货</th>
        </tr>
        <tr th:each="prod,iterStat:${prods}" th:class="${iterStat.odd}?'odd'">
            <td th:text="${prod.name}">土豆</td>
            <td th:text="${prod.price}">2.41</td>
            <td th:text="${prod.inStock}?#{true}:#{false}">yes</td>
        </tr>
    </table>
    <p>
        <a href="../home.html" th:href="@{/}">返回首页</a>
    </p>
    复制代码

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

    复制代码
    <ol>  
            <li>List循环:  
                <table border="1">  
                  <tr>  
                    <th>用户名</th>  
                    <th>邮箱</th>  
                    <th>管理员</th>  
                    <th>状态变量:index</th>  
                    <th>状态变量:count</th>  
                    <th>状态变量:size</th>  
                    <th>状态变量:current.userName</th>  
                    <th>状态变量:even</th>  
                    <th>状态变量:odd</th>  
                    <th>状态变量:first</th>  
                    <th>状态变量:last</th>  
                  </tr>  
                  <tr  th:each="user,userStat : ${list}">  
                    <td th:text="${user.userName}">Onions</td>  
                    <td th:text="${user.email}">test@test.com.cn</td>  
                    <td th:text="${user.isAdmin}">yes</td>  
                     <th th:text="${userStat.index}">状态变量:index</th>  
                    <th th:text="${userStat.count}">状态变量:count</th>  
                    <th th:text="${userStat.size}">状态变量:size</th>  
                    <th th:text="${userStat.current.userName}">状态变量:current</th>  
                    <th th:text="${userStat.even}">状态变量:even****</th>  
                    <th th:text="${userStat.odd}">状态变量:odd</th>  
                    <th th:text="${userStat.first}">状态变量:first</th>  
                    <th th:text="${userStat.last}">状态变量:last</th>  
                  </tr>  
                </table>  
            </li>  
            <li>Map循环:  
                <div th:each="mapS:${map}">  
                <div th:text="${mapS}"></div>  
                </div>  
            </li>  
            <li>数组循环:  
                <div th:each="arrayS:${arrays}">  
                <div th:text="${arrayS}"></div>  
                </div>  
            </li>  
            </ol>
    复制代码

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

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

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

    例如:

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

     

    <div th: fragment=" copy" >
    
    © 2011 The Good Thymes Virtual Grocery
    
    </div>

     

    引入模板片段:

    <div th: include=" /templates/footer : : copy" ></div>
    
    <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类似,但是他插入的是片段的内容,而不是片段。

    还是举个例子吧:

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

    导入到两个div标签中:

    复制代码
    <body>
        ...
        <div th:insert="footer :: copy"></div>
        <div th:replace="footer :: copy"></div>
        <div th:include="footer :: copy"></div>
    </body>
    复制代码

    执行结果:

    复制代码
    <body>
      ...
      <div>
        <footer>
            &copy; 网络商店
        </footer>
      </div>
      <footer>
        &copy; 网络商店
      </footer>
      <div>
          &copy; 网络商店
      </div>
    </body>
    复制代码

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

    复制代码
    <form action="subscribe.html" th:attr="action=@{/subscribe}">
      <fieldset>
        <input type="text" name="email" />
        <input type="submit" value="订阅!" th:attr="value=#{subscribe.submit}"/>
      </fieldset>
    </form>
    复制代码

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

    复制代码
    <form action="/gtvg/subscribe">
      <fieldset>
        <input type="text" name="email" />
        <input type="submit" value="subscribe me!"/>
      </fieldset>
    </form>
    复制代码

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

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

    将转换为:

    <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"的状态变量。

    下面大家看下例子:

     

    复制代码
    <form id="login-form" th:action="@{/addStudent}" th:object="${stuReqBean}" method="POST">
    
      <div class="student" th:each="stuIter,rowStat:${stuReqBean.students}">
    
        <input type="text" class="firstName" value="" th:field="*{students[__${rowStat.index}__].firstName}"></input>
    
        <input type="text" class="school" value="" th:field="*{students[__${rowStat.index}__].school}"></input>
    
      </div>
    </form>
    复制代码

     

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

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

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

    List<Student > stus = new ArrayList<Student >();
    
    stus .add(new Student ());
    
    StudentRequestBean.setStudents(stus );

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

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

    复制代码
    <table>
        <tr>
            <th>食物名称</th>
            <th>食物价格</th>
            <th>可现做</th>
            <th>食客评价</th>
        </tr>
        <tr th:each="prod:${prods}">
            <td th:text="${prod.name}">醋溜土豆丝</td>
            <td th:text="${#numbers.formatDecimal(prod.price,0,2)}">2.41</td>
            <td th:text="${prod.isReady}?#{true}:#{false}">yes</td>
            <td>
                <span th:text=${#lists.size(prod.comments)}>2</span>个评价
                <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}"
                th:if="${not #lists.isEmpty(prod.comments)}">查看</a>
            </td>
        </tr>
    </table>
    复制代码

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

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

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

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

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

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

    复制代码
    <h1>产品列表</h1>
    <table>
        <tr>
            <th>产品名称</th>
            <th>产品价格</th>
            <th>有现货</th>
        </tr>
        <tr th:each="prod,iterStat:${prods}" th:class="${iterStat.odd}?'odd'">
            <td th:text="${prod.name}">土豆</td>
            <td th:text="${prod.price}">2.41</td>
            <td th:text="${prod.inStock}?#{true}:#{false}">yes</td>
        </tr>
    </table>
    <p>
        <a href="../home.html" th:href="@{/}">返回首页</a>
    </p>
    复制代码

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

    复制代码
    <ol>  
            <li>List循环:  
                <table border="1">  
                  <tr>  
                    <th>用户名</th>  
                    <th>邮箱</th>  
                    <th>管理员</th>  
                    <th>状态变量:index</th>  
                    <th>状态变量:count</th>  
                    <th>状态变量:size</th>  
                    <th>状态变量:current.userName</th>  
                    <th>状态变量:even</th>  
                    <th>状态变量:odd</th>  
                    <th>状态变量:first</th>  
                    <th>状态变量:last</th>  
                  </tr>  
                  <tr  th:each="user,userStat : ${list}">  
                    <td th:text="${user.userName}">Onions</td>  
                    <td th:text="${user.email}">test@test.com.cn</td>  
                    <td th:text="${user.isAdmin}">yes</td>  
                     <th th:text="${userStat.index}">状态变量:index</th>  
                    <th th:text="${userStat.count}">状态变量:count</th>  
                    <th th:text="${userStat.size}">状态变量:size</th>  
                    <th th:text="${userStat.current.userName}">状态变量:current</th>  
                    <th th:text="${userStat.even}">状态变量:even****</th>  
                    <th th:text="${userStat.odd}">状态变量:odd</th>  
                    <th th:text="${userStat.first}">状态变量:first</th>  
                    <th th:text="${userStat.last}">状态变量:last</th>  
                  </tr>  
                </table>  
            </li>  
            <li>Map循环:  
                <div th:each="mapS:${map}">  
                <div th:text="${mapS}"></div>  
                </div>  
            </li>  
            <li>数组循环:  
                <div th:each="arrayS:${arrays}">  
                <div th:text="${arrayS}"></div>  
                </div>  
            </li>  
            </ol>
    复制代码

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

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

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

    例如:

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

     

    <div th: fragment=" copy" >
    
    © 2011 The Good Thymes Virtual Grocery
    
    </div>

     

    引入模板片段:

    <div th: include=" /templates/footer : : copy" ></div>
    
    <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类似,但是他插入的是片段的内容,而不是片段。

    还是举个例子吧:

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

    导入到两个div标签中:

    复制代码
    <body>
        ...
        <div th:insert="footer :: copy"></div>
        <div th:replace="footer :: copy"></div>
        <div th:include="footer :: copy"></div>
    </body>
    复制代码

    执行结果:

    复制代码
    <body>
      ...
      <div>
        <footer>
            &copy; 网络商店
        </footer>
      </div>
      <footer>
        &copy; 网络商店
      </footer>
      <div>
          &copy; 网络商店
      </div>
    </body>
    复制代码

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

    复制代码
    <form action="subscribe.html" th:attr="action=@{/subscribe}">
      <fieldset>
        <input type="text" name="email" />
        <input type="submit" value="订阅!" th:attr="value=#{subscribe.submit}"/>
      </fieldset>
    </form>
    复制代码

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

    复制代码
    <form action="/gtvg/subscribe">
      <fieldset>
        <input type="text" name="email" />
        <input type="submit" value="subscribe me!"/>
      </fieldset>
    </form>
    复制代码

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

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

    将转换为:

    <img src="/gtgv/images/gtvglogo.png" title="这里是logo" alt="这里是logo" />
  • 相关阅读:
    MySQL (一)(未完成)
    HTML 学习笔记 CSS3 (边框)
    HTML 学习笔记 JavaScript (函数)
    HTML 学习笔记 JavaScript (对象)
    HTML 学习笔记 JavaScript (变量)
    HTML 学习笔记 JavaScript (实现)
    HTML 学习笔记 JavaScript(简介)
    iOS RunTime运行时(1):类与对象
    iOS UITableView 分割线从零开始
    HTML 学习笔记 CSS(选择器4)
  • 原文地址:https://www.cnblogs.com/xiaolovewei/p/8795724.html
Copyright © 2011-2022 走看看