在每个中使用动态变量

huangapple go评论91阅读模式
英文:

Using dynamic variable in each

问题

I want 0 in images.foo0bar to be replaced by index:

要将images.foo0bar中的0替换为index,可以使用Thymeleaf的内联表达式来实现:

  1. <th:block th:each="someData, index : ${someData.from.somewhere}">
  2. <th:block th:each="image : ${images[__${'foo' + index + 'bar'}__]}">
  3. <img th:src="${image}"/>
  4. </th:block>
  5. <hr/>
  6. </th:block>

上面的代码中,${'foo' + index + 'bar'}会将0替换为index。注意使用双下划线__来包裹这个表达式以确保它在Thymeleaf中正确解析。

英文:
  1. &lt;th:block th:each=&quot;someData, index : ${someData.from.somewhere}&quot;&gt;
  2. &lt;th:block th:each=&quot;image : ${images.foo0bar}&quot;&gt;
  3. &lt;img th:src=&quot;${image}&quot;/&gt;
  4. &lt;/th:block&gt;
  5. &lt;hr/&gt;
  6. &lt;/th:block&gt;

I want 0 in images.foo0bar to be replaced by index

How do I do something like th:each=&quot;image : ${images.foo + index + bar}&quot;

答案1

得分: 4

您可以使用Thymeleaf的预处理器来执行基于串联字符串的getter方法:

  1. &lt;th:block th:each=&quot;someData, iterstat : ${someData}&quot;&gt;
  2. &lt;th:block th:with=&quot;imageField=|images.foo${iterstat.index}bar|&quot;&gt;
  3. &lt;th:block th:each=&quot;image : ${__${imageField}__}&quot;&gt;
  4. &lt;img th:src=&quot;${image}&quot;&gt;
  5. &lt;/th:block&gt;
  6. &lt;/th:block&gt;
  7. &lt;/th:block&gt;

在上面的方法中,th:with=&quot;imageField=...&quot; 用于构建您所需的字符串:

  1. images.foo0bar
  2. images.foo1bar
  3. ...以此类推...

然后,将该 imageField 变量与Thymeleaf的预处理语法一起使用,将其视为您的 images 对象中的字段名。


更新

我先前的解决方案中有一个错误,如最初写的那样。而不是:

  1. __${imageField}__

应该是:

  1. ${__${imageField}__}

换句话说,我忘了将预处理器的结果包装在Thymeleaf表达式中,以便检索每个列表中的实际对象(图像URL)。

我已经进行了更正。

为了背景,这是我用于Thymeleaf模型的测试数据:

  1. List&lt;String&gt; someData = Stream.of(&quot;abc&quot;, &quot;def&quot;, &quot;ghi&quot;)
  2. .collect(Collectors.toList());
  3. List&lt;String&gt; a = Stream.of(&quot;1&quot;, &quot;2&quot;, &quot;3&quot;)
  4. .collect(Collectors.toList());
  5. List&lt;String&gt; b = Stream.of(&quot;4&quot;, &quot;5&quot;, &quot;6&quot;)
  6. .collect(Collectors.toList());
  7. List&lt;String&gt; c = Stream.of(&quot;7&quot;, &quot;8&quot;)
  8. .collect(Collectors.toList());
  9. Images images = new Images();
  10. images.setFoo0bar(a);
  11. images.setFoo1bar(b);
  12. images.setFoo2bar(c);
  13. Map&lt;String, Object&gt; model = new HashMap&lt;&gt;();
  14. model.put(&quot;someData&quot;, someData);
  15. model.put(&quot;images&quot;, images);

而且我的 Images 类包含这3个字段:

  1. private List&lt;String&gt; foo0bar;
  2. private List&lt;String&gt; foo1bar;
  3. private List&lt;String&gt; foo2bar;

只是一个建议...

支持这一点的Java对象似乎有点复杂,背后的实现也不太直接。

您有一个 someData 集合,您不会直接访问它,只是用来迭代其内容的计数。

然后,您使用这个计数来构建一个字段名,以便执行相关的getter方法,然后迭代完全不同(似乎无关)对象中的图像URL集合。

只是一个建议:如果重新排列您的Java数据,您可以避免这种Thymeleaf的复杂性。

英文:

You can use Thymeleaf's preprocessor to execute a getter based on a concatenated string:

  1. __${...}__

For example:

  1. &lt;th:block th:each=&quot;someData, iterstat : ${someData}&quot;&gt;
  2. &lt;th:block th:with=&quot;imageField=|images.foo${iterstat.index}bar|&quot;&gt;
  3. &lt;th:block th:each=&quot;image : ${__${imageField}__}&quot;&gt;
  4. &lt;img th:src=&quot;${image}&quot;&gt;
  5. &lt;/th:block&gt;
  6. &lt;/th:block&gt;
  7. &lt;/th:block&gt;

In the above approach, the th:with=&quot;imageField=...&quot; is used to build the string you need:

  1. images.foo0bar
  2. images.foo1bar
  3. ... and so on...

That imageField variable is then used with the Thymeleaf preprocessing syntax to handle it as a field name in your images object.


UPDATE

My solution above had a mistake, as originally written. Instead of this:

  1. __${imageField}__

It should be this:

  1. ${__${imageField}__}

In other words, I forgot to wrap the pre-processor results in a Thymeleaf expression - so that the actual objects in each list (of image URLs) are retrieved.

I corrected this, above.

For backgound, here is the test data I used for the Thymeleaf model:

  1. List&lt;String&gt; someData = Stream.of(&quot;abc&quot;, &quot;def&quot;, &quot;ghi&quot;)
  2. .collect(Collectors.toList());
  3. List&lt;String&gt; a = Stream.of(&quot;1&quot;, &quot;2&quot;, &quot;3&quot;)
  4. .collect(Collectors.toList());
  5. List&lt;String&gt; b = Stream.of(&quot;4&quot;, &quot;5&quot;, &quot;6&quot;)
  6. .collect(Collectors.toList());
  7. List&lt;String&gt; c = Stream.of(&quot;7&quot;, &quot;8&quot;)
  8. .collect(Collectors.toList());
  9. Images images = new Images();
  10. images.setFoo0bar(a);
  11. images.setFoo1bar(b);
  12. images.setFoo2bar(c);
  13. Map&lt;String, Object&gt; model = new HashMap&lt;&gt;();
  14. model.put(&quot;someData&quot;, someData);
  15. model.put(&quot;images&quot;, images);

And my Images class contains these 3 fields:

  1. private List&lt;String&gt; foo0bar;
  2. private List&lt;String&gt; foo1bar;
  3. private List&lt;String&gt; foo2bar;

Just a suggestion...

The Java objects which support this appear to be a bit convoluted, behind the scenes.

You have a collection of someData which you do not directly access, except to iterate through a count of its contents.

You then use this count to build a field name, so you can executed the related getter - and iterate through that collection of image URLs, in a completely different (seemingly unrelated) object.

Just as a suggestion: If you re-arrange your Java data, you could avoid this Thymeleaf complexity.

huangapple
  • 本文由 发表于 2023年2月19日 19:45:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75499896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定