【问题标题】:How to display iteration index in Thymeleaf? [duplicate]如何在 Thymeleaf 中显示迭代索引? [复制]
【发布时间】:2022-01-11 00:54:50
【问题描述】:

我正在尝试使用 Thymeleaf 显示数组中的每一行 - 在他们的 documentation 之后,我无法使用 th:each 中的以下任何属性:

  • 当前迭代索引,从0开始。这是索引 属性。

  • 当前迭代索引,从 1 开始。这是计数 属性。

userinput.html:

 <tr th:each="year : ${years}">
      <th scope="row" th:text="${years}"></th>
      <th scope="row" th:text="${bdcInterest}"></th>
      <td th:text="${bdAmount}"></td>
 </tr>

CalculatorController.java:

    @RequestMapping(value = "/submit", method = RequestMethod.GET)
public String userInput(Model model, BigDecimal lumpsum, BigDecimal interestrate, BigDecimal monthlywithdrawal) {
    
    BigDecimal initialinvestment = lumpsum;
    
    BigDecimal[] bdAmount = new BigDecimal[11];
    BigDecimal[] bdcInterest = new BigDecimal[11];
    BigDecimal[] initialInvestment = new BigDecimal[11];
    int[] years = new int[11];
    
    bdcInterest[0] = new BigDecimal(0);
    initialInvestment[0] = initialinvestment;
    
    int increment = 1;

    while(increment < 10) {

        BigDecimal amount = lumpsum
                .multiply(BigDecimal
                        .valueOf(1)
                        .add(interestrate
                                .divide(BigDecimal
                                        .valueOf(100)))
                        .subtract(monthlywithdrawal
                                .multiply(BigDecimal
                                        .valueOf(12)))); // Calculate the total yearly amount
        
        BigDecimal cInterest = amount.subtract(initialinvestment); // Calculate only the interest earned 

        bdAmount[increment] = amount;
        bdcInterest[increment] = cInterest;
        initialInvestment[increment] = initialinvestment;
        years[increment] = increment;
        
        lumpsum = amount;

        increment++;
    }
    
    model.addAttribute("years", years);
    model.addAttribute("initialInvestment", initialInvestment);
    
    model.addAttribute("bdAmount", bdAmount);
    model.addAttribute("bdcInterest", bdcInterest);

    return "userinput";

}

在各个数组中正确提交了必要的数据,但是我相信我误解了文档:

【问题讨论】:

  • 在您的 Thymeleaf 表达式 th:each="year,id : ${increment}" 中,${increment} 是什么?它应该评估为一个列表或一个数组——Thymeleaf 可以迭代的东西。在你的情况下,它似乎没有评估任何东西。您是否要迭代 ${year} 或类似的东西?目前尚不清楚预期的结果是什么。 (如果您的 Java 变量是用于列表/数组的复数形式,也可能会更清楚一些 - 例如,years 而不是 year。)
  • 我的猜测,基于上述评论:th:each="year : ${years}" - 假设您将 Java 变量从 year 更改为 years
  • @andrewJames 感谢您的回复 - 我刚刚更新了上面的代码。希望这可以澄清 - Thymeleaf 表达式 &lt;tr th:each="year : ${years}"&gt; 旨在遍历数组,每年显示相关信息。它currently displays the memory location 为每个数组,而不是里面的信息。我在这里哪里出错了?感谢您的宝贵时间
  • 您仍在尝试在此处显示${years}&lt;th scope="row" th:text="${years}"&gt;&lt;/th&gt;。应该是th:text="${year}"。然后您还尝试在此处显示对象数组:th:text="${bdcInterest}" 和此处:th:text="${bdAmount}",而不是访问每个数组中的特定索引。
  • 考虑到你的方法(使用多个数组),你也让事情变得比他们需要的更复杂。相反,您应该考虑创建一个包含对象的 Java List,其中每个对象包含一个年份值,以及利息、投资、金额的相关值。在这种情况下,Thymeleaf 迭代变得更加简洁和简单。

标签: thymeleaf


【解决方案1】:

Thymeleaf 在一个特殊变量中维护th:each 标签的迭代状态。请参阅relevant documentation

在该变量提供的不同信息中,您可以找到一个index 属性,它对应于实际的迭代索引。

在您的示例中,您可能可以像这样迭代您的结果:

 <tr th:each="year, iterStat : ${years}">
      <th scope="row" th:text="${year}"></th>
      <th scope="row" th:text="${bdcInterest[iterStat.index]}"></th>
      <td th:text="${bdAmount[iterStat.index]}"></td>
 </tr>

为避免此类问题,请考虑在您的代码中定义一个简单的 java 对象,该对象将您正在迭代的四个属性粘合起来:

public class MuCustomObject {
  private BigDecimal bdAmount;
  private BigDecimal bdcInterest;
  private BigDecimal initialInvestment;
  private int year;

  // getters and setters omitted for brevity
}

然后,使用控制器中的对象:

    @RequestMapping(value = "/submit", method = RequestMethod.GET)
public String userInput(Model model, BigDecimal lumpsum, BigDecimal interestrate, BigDecimal monthlywithdrawal) {
    
    BigDecimal initialinvestment = lumpsum;
    
    List<MyCustomObject> myCustomObjectList = new ArrayList<MyCustomObject>();
    
    MyCustomObject myCustomObject = new MyCustomObject();
    myCustomObject.setBdcInterest(new BigDecimal(0));
    myCustomObject.setInitialInvestment(initialinvestment);
    myCustomObjectList.add(myCustomObject);
    
    int increment = 1;

    while(increment < 10) {

        BigDecimal amount = lumpsum
                .multiply(BigDecimal
                        .valueOf(1)
                        .add(interestrate
                                .divide(BigDecimal
                                        .valueOf(100)))
                        .subtract(monthlywithdrawal
                                .multiply(BigDecimal
                                        .valueOf(12)))); // Calculate the total yearly amount
        
        BigDecimal cInterest = amount.subtract(initialinvestment); // Calculate only the interest earned 

        myCustomObject = new MyCustomObject();
        myCustomObject.setBdAmount(amount);
        myCustomObject.setBdcInterest(cInterest);
        myCustomObject.setInitialInvestment(initialinvestment);
        myCustomObject.setYear(increment);
        myCustomObjectList.add(myCustomObject);
        
        lumpsum = amount;

        increment++;
    }
    
    model.addAttribute("myCustomObjects", myCustomObjectList);

    return "userinput";

}

使用这些信息,您可以直接迭代集合:

 <tr th:each="myCustomObject, iterStat : ${myCustomObjects}">
      <th scope="row" th:text="${myCustomObject.year}"></th>
      <th scope="row" th:text="${myCustomObject.bdcInterest}"></th>
      <td th:text="${myCustomObject.bdAmount}"></td>
 </tr>

【讨论】:

  • 欢迎您@PublicDisplayName。我很高兴听到它工作正常。无论如何,我都更新了答案,为您提供可能的优化。请使用您认为合适的命名约定——我的意思是,去掉MyCustomObject。我希望它有所帮助。
猜你喜欢
  • 2014-01-23
  • 1970-01-01
  • 2020-08-02
  • 2020-01-30
  • 2018-08-14
  • 1970-01-01
  • 2011-05-27
  • 2015-09-19
  • 1970-01-01
相关资源
最近更新 更多