【问题标题】:Continuous numeration of nested loop items in ThymeleafThymeleaf 中嵌套循环项的连续计数
【发布时间】:2015-03-29 23:33:11
【问题描述】:

我正在编写一个应该呈现员工列表的模板。员工以部门列表的形式传递给 Thymeleaf,每个部门都有自己的员工列表。

因为我的任务是全部显示 - 问题是处理连续编号。每个员工都应显示为一行,并带有下一个数字。

以下尝试允许索引给定部门的员工,每个部门都有新的编号:

<table th:each="department, depStatus : departmentList">
    <tr th:each="employee, empStatus : department.employees">
        <td th:inline="text">[[${empStatus.index+1}]]</td>

但我的意思是在所有部门中保持连续计数,就像这样:

1. Employee A from Dept X
2. Employee B from Dept X
3. Employee C from Dept Y

我知道我可以在服务器端使这个结构变平,但我不敢相信这是唯一的方法。

我还尝试使用th:with="idx = 0" 引入局部变量,然后使用th:with="idx = ${idx} + 1 在某处增加它,但这只是覆盖了外部idx 值。

【问题讨论】:

  • 我不是很喜欢这个,但是那个解释不能帮助一点吗? forum.thymeleaf.org/…。似乎问题的所有者尝试了与您相同的 th:with 并得到了答案,为什么它不可能以及他需要如何处理。

标签: java thymeleaf


【解决方案1】:

您试图实现的是更新局部变量并让新值在比进行更新的范围更广的范围内可见。这就是它与 th:with 定义相矛盾的原因。 我认为您无法避免进行一些服务器端调整,例如按照您的建议提供一些更平坦的结构视图。

另一方面,一个快速的解决方案,(假设您不严格使用表格)它可能会在使用 th:blocks 作为封闭部门时尝试有序列表:

<ol>
  <!--/*/ <th:block th:each="dept : ${departmentList} "> /*/-->

   <li th:each="emp : dept.employees" th:text="|${emp.name} from ${dept.name}|"></li>

  <!--/*/ </th:block> /*/-->
</ol>  

【讨论】:

  • 这是开箱即用的想法! :)
  • 我设法以某种方式结合了tableol 标签。 &lt;ol&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;li&gt;a&lt;/li&gt;&lt;/td&gt;&lt;td&gt;test&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/ol&gt; 虽然它是无效 html,但我的渲染器处理得很好,它是我的目标。谢谢!
【解决方案2】:

让我们看看我是否理解您的问题:

您有一个将员工分配到部门的模型。根据您对问题的描述,一个部门对象有一个分配给它的员工列表。

据我所见,你正在从你的控制器类到你的愿景一个部门的集合。

您已经知道,Thymeleaf 可以通过 th:each 属性在元素中使用迭代。您可以稍微减少只在员工集合中执行迭代的代码,例如:

<table>
    <tr th:each="employee, empStatus : ${department.employees}">

注意:如果我没记错的话,你的模板结果会重复 由于部门数量而导致的表格元素。

这样,您的代码会更简洁,您可以只专注于与员工合作。


关于每行索引定义的主要问题,您可以使用称为“迭代状态”的东西。

我相信您已经对此有所了解,但我会尝试解释我的方式,这可能会给您一些启发:

根据 Thymeleaf 文档,您可以使用 Thymeleaf 提供的变量,它可以让您访问有关正在进行的迭代的一些信息。使用此变量,您可以收集一些信息,其属性在Thymeleaf documentation 中引用(检查会话 6.2):

当前迭代索引,从 0 开始。这是 索引 财产。当前迭代索引,从 1 开始。这是 count 属性。迭代变量中的元素总数。 这是 size 属性。每次迭代的 iter 变量。这 是 当前 属性。当前迭代是偶数还是奇数。 这些是 偶数/奇数 布尔属性。当前是否 迭代是第一个。这是 first 布尔属性。 当前迭代是否是最后一个。这是最后一个 布尔属性。

要访问此变量,您需要在表示每次迭代的项目声明之后立即声明它,就像您之前所做的那样:

<tr th:each="employee, empStatus : ${department.employees}">

您也可以省略该变量的声明并仍然使用它。这是唯一可能的,因为 Thymeleaf 向您做出此声明,其中它采用赋予表示每个迭代元素的变量的名称(在本例中为“employee”),并向其添加后缀“Stat”(导致“employeeStat”) .

您只能在带有 th:each 属性的标记定义的代码片段中访问此变量及其内部属性。

如果您知道如何在 Web 应用程序页面中显示行和列,您所要做的就是使用迭代状态变量的属性,例如:

<td th:text="${empStatus.index}"></td>

或者,如果您愿意:

<td th:text="${empStatus.count}"></td>

如果您有任何问题,请发表评论,我将编辑我的答案以更好地理解。


编辑

哦,我现在才明白你真正的问题是什么,抱歉。

如果您想创建一个列表,其中每个员工的姓名后跟其各自部门的名称,并且每个列表项都有不同的编号(全部指定),那么问题就很简单了。

您首先要做的就是遍历所有部门,根据需要显示员工姓名后跟部门名称。这将解决部分问题,因为这只是逻辑和迭代使用的简单问题。

为了使这种情况定期发生,即按顺序列出每条记录/项目,例如,您可以创建一个局部变量,它是 Thymeleaf 中的其他资源之一。

要快速了解设置和使用此类资源,请查看此链接:setting up a value for a variable name in thymeleaf

或者您可以查看 Thymeleaf (Session 9) 的文档:http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#local-variables

创建变量后,尝试将其用作计数器,其中列出的每条记录都会递增。

我希望这对您有所帮助并解决您的问题。如果这不起作用,请再次发表评论,我将尝试另一种解决方案。同样,如果这不是您的问题,也请发表评论。

注意:我再次要求您小心循环结构。你可能会 创建创建多个表结构的重复结构 在 HTML 代码中,我相信这不是你想要的。此外,请确保检查您是否正确执行算术运算。我相信您的增量操作必须在大括号 {} 内,而不是在大括号之外。


编辑 2

为了做到这一点,我到处搜索......但不幸的是我只能找到这个:

Counters in Loops in Thymeleaf

您可以在 Thymeleaf 文档(附录 B - 编号)中找到更多相关信息。这是使用 Thymeleaf 进行循环的有效方法。但是,很难进行嵌套循环,因为我们在 Thymeleaf 中使用属性而不是标签/ HTML 元素。以防万一,您只能在嵌套循环中创建新行,这是不可能的。也许你可以尝试在同一个“tr”标签中使用两次“th:each”属性,如:

<tr th:each="" th:each"">
</tr>

虽然我相信这也行不通……

Maciej,我真的很抱歉,因为这不是最终答案,因此并没有真正的帮助。但是,我请您稍等片刻,并尝试查看您的 Web 应用程序。试想一下,你想设计一张桌子,订购东西,用数字列出所有东西。在 Java 代码中执行此操作不是更好吗?此外,您不会尝试在 SQL 中执行此操作吗?您不想使用 SQL 获得数据库的排序结果吗?意识到您正在使一个组织在这里工作,每个部门的每个员工都将被列出,部门按顺序排列。

你看,我并不是说你做错了,但是在这种情况下,如果我们停下来分析一下,我们开发人员通常会从应用程序的业务层得到有序的结果,我们让视图层只负责显示它们。

如果这在您的应用程序中是不可能的,并且我现在发送给您的链接无法指导您解决您的问题,那么我非常抱歉,但我无能为力。也许是时候在 Thymeleaf 论坛中提出这个问题了,它的开发人员可能会帮助你(可能):

http://forum.thymeleaf.org/General-Usage-f2234430.html

我真诚地希望您能成功解决您的问题。如果你这样做了,我恳请你在这里与大家分享你的解决方案,因为很多人有一天可能会面临同样的情况。

Até depois, e boa sorte amigo。

【讨论】:

  • 请注意,我在问题的代码中使用了 iteration status,我真的知道这是做什么用的以及它是如何工作的等等。我现在已经用我正在寻找的示例更新了我的问题。请注意,有两个 嵌套集合,我正在寻找的是它们的 连续 编号。
  • 抱歉,我没有阅读您编辑的最后部分。我相信您在问题中使用的表达式中使用的加号 (+) 将连接字符文字(即字母),而不是按照您的意愿增加数字。从 Thymeleaf 文档中阅读会话 4.8 并重试。
  • 我知道你设置了一个嵌套循环结构(正如你所说的“嵌套集合”),至少这是你的代码中出现的内容。但是,请注意您的操作方式。如果您想创建一个包含记录的表格,请仅重复 HTML 代码中的行,而不是表格结构本身。除非你想创建不同的表结构,否则不要这样做: 因为它会重复你的表元素等于部门记录的数量。
  • 我问题的最后一段是尝试使用局部变量(使用th:with)。不幸的是,它在递增时效果不佳,看起来声明的变量仅在“局部范围”中被覆盖(当内部集合的迭代结束时,变量的值恢复为原始值 - 迭代开始之前的值)。
  • 对不起,如果我问,但你不会做错了吗?我的意思是,根据你的最后一段,你两次声明同一个变量。属性“th:with”被用作声明点,而不是处理或更改已声明的变量值。也许您应该在某一时刻声明该变量,然后在另一时刻使用它。为此,请尝试使用“with”属性声明您的变量,并在其范围内(在元素内部)在某些时候使用变量表达式($ {})来更改其值。请尝试一下,如果可能的话,给我反馈。 :)
【解决方案3】:
    <div th:each="department : ${departmentList}">
        <div th:each="employee : ${department.employees}">
            <div th:text="${#ids.seq ('')}"></div>
        </div>
    </div>

请参阅文档https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#ids

https://www.tutorialfor.com/questions-69803.htm致敬

【讨论】:

    【解决方案4】:

    对于任何与循环相关的操作,您应该能够使用iterationStatus 实用程序

    查看以下代码以显示迭代项的索引。

     <tr th:each="emp,iterStat : ${employess}">
            <td th:text="${iterStat.count}"></td>
            <td th:text="${emp.name}"></td>
            <td th:text="${emp.department}"></td>
      </tr>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-20
      • 2018-02-14
      • 2018-05-06
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多