在每个中使用动态变量

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

Using dynamic variable in each

问题

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

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

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

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

英文:
&lt;th:block th:each=&quot;someData, index : ${someData.from.somewhere}&quot;&gt;
    &lt;th:block th:each=&quot;image : ${images.foo0bar}&quot;&gt;
        &lt;img th:src=&quot;${image}&quot;/&gt;
    &lt;/th:block&gt;
    &lt;hr/&gt;
&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方法:

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

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

images.foo0bar  
images.foo1bar  
...以此类推...

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


更新

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

__${imageField}__

应该是:

${__${imageField}__}

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

我已经进行了更正。

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

List&lt;String&gt; someData = Stream.of(&quot;abc&quot;, &quot;def&quot;, &quot;ghi&quot;)
        .collect(Collectors.toList());

List&lt;String&gt; a = Stream.of(&quot;1&quot;, &quot;2&quot;, &quot;3&quot;)
        .collect(Collectors.toList());
List&lt;String&gt; b = Stream.of(&quot;4&quot;, &quot;5&quot;, &quot;6&quot;)
        .collect(Collectors.toList());
List&lt;String&gt; c = Stream.of(&quot;7&quot;, &quot;8&quot;)
        .collect(Collectors.toList());

Images images = new Images();
images.setFoo0bar(a);
images.setFoo1bar(b);
images.setFoo2bar(c);

Map&lt;String, Object&gt; model = new HashMap&lt;&gt;();
model.put(&quot;someData&quot;, someData);
model.put(&quot;images&quot;, images);

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

private List&lt;String&gt; foo0bar;
private List&lt;String&gt; foo1bar;
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:

__${...}__

For example:

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

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

images.foo0bar  
images.foo1bar  
... 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:

__${imageField}__

It should be this:

${__${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:

List&lt;String&gt; someData = Stream.of(&quot;abc&quot;, &quot;def&quot;, &quot;ghi&quot;)
        .collect(Collectors.toList());

List&lt;String&gt; a = Stream.of(&quot;1&quot;, &quot;2&quot;, &quot;3&quot;)
        .collect(Collectors.toList());
List&lt;String&gt; b = Stream.of(&quot;4&quot;, &quot;5&quot;, &quot;6&quot;)
        .collect(Collectors.toList());
List&lt;String&gt; c = Stream.of(&quot;7&quot;, &quot;8&quot;)
        .collect(Collectors.toList());

Images images = new Images();
images.setFoo0bar(a);
images.setFoo1bar(b);
images.setFoo2bar(c);

Map&lt;String, Object&gt; model = new HashMap&lt;&gt;();
model.put(&quot;someData&quot;, someData);
model.put(&quot;images&quot;, images);

And my Images class contains these 3 fields:

private List&lt;String&gt; foo0bar;
private List&lt;String&gt; foo1bar;
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:

确定