##Mark一个关于Thymeleaf 使用th:field属性与对象属性绑定的小问题
最近在尝试用Spring Boot + Thymeleaf搭建一个个人博客,其中Article类中有一个属性如下定义:
private List<String> contentParagraphs;
需求是将前端页面的textarea文本域与contentParagraphs属性绑定,而前端页面的textarea大部分是经由javascript代码生成的:
var $textArea = $("<textarea></textarea>");
$textArea.attr("some attr","some value");
...
$inputField.append($textArea);
像这样,使用JS代码往网页中动态添加一个输入域。页面中默认具有一个输入域(绑定一个段落),点击按钮可以增加一个输入域。
默认情况:
点击加号按钮:
比较关键的,默认输入域域中用于和段落进行绑定的前端代码如下,主要是th:field属性起到绑定作用,这样使这个textarea绑定到contentParagraphs[0],即第一个段落。
<textarea th:field="${article.contentParagraphs[0]}" id="contentParagraph0" required="required" class="materialize-textarea"></textarea>
那么如何将增加的输入域和下一个段落进行绑定呢?很自然地会沿用默认域的写法,但是把中括号里的0改成其他数字就行了。所以一开始我的JS代码是这样的:
$textArea.attr("th:field","${article.contentParagraphs["+currentLocation+"]}");
但是这样点击提交按钮后,后台只接收到了默认输入域的文本。很揪心。
不过通过Chrome浏览器的检查元素功能,查看默认输入域的HTML代码如下:
<textarea id="contentParagraph0" required="required" class="materialize-textarea" name="contentParagraphs[0]"></textarea>
是不是很惊讶!压根没有th:field属性,而变成了name=contentParagraphs[0]
属性。再查看增加的输入域HTML代码如下:
<textarea id="contentParagraph1" required="required" class="materialize-textarea" th:field="${article.contentParagraphs[1]}"></textarea>
终于发现问题所在了吧!推测这是因为Thymeleaf在浏览器解析页面的时候把th:field属性自动转换成name属性了。所以把JS中绑定段落的代码改成设置name属性就OK了。
$textArea.attr("name","contentParagraphs["+currentLocation+"]");
点击提交按钮,后台成功接收到增加的输入域文本(后台代码打印contentParagraphs属性)。