参考对象传递给Thymeleaf片段

时间:2017-04-11 18:27:50

标签: spring-mvc parameter-passing thymeleaf

我有一个Parent类,它在ParentForm支持类中实例化为母亲和父亲两次。 Web表单要求将每个Parent的名字和姓氏验证为NotNull。我专门为"母亲制作了一个Thymeleaf片段。实例,但我想让两个父实例的片段都是通用的:

<div class="form-group" th:fragment="name">
    <div class="form-row clearfix">
        <div th:classappend="${#fields.hasErrors('mother.firstName') or #fields.hasErrors('mother.lastName')} ? has-error : ''">
            <label class="control-label col-xs-12" th:classappend="${#fields.hasErrors('mother.firstName') or #fields.hasErrors('mother.lastName')} ? has-error : ''">What is the mother's name?</label>
        </div>
        <div class="col-sm-11 col-sm-offset-1 col-xs-12">
            <div class="form-row form-group">
                <div th:classappend="${#fields.hasErrors('mother.firstName')} ? has-error : ''" class="col-xs-12 col-sm-6">
                    <div class="input-group">
                        <label th:for="mother.firstName" class="control-label">First&nbsp;</label>
                        <input type="text" th:field="*{mother.firstName}" th:value="*{mother.firstName}" class="form-control"/>
                    </div> 
                </div>
                <div th:classappend="${#fields.hasErrors('mother.lastName')} ? has-error : ''" class="col-xs-12 col-sm-6">
                    <div class="input-group">
                        <label th:for="mother.lastName" class="control-label">Last&nbsp;</label>
                        <input type="text" th:field="*{mother.lastName}" th:value="*{mother.lastName}" class="form-control"/>
                    </div> 
                </div>
            </div>
        </div>
    </div>
    <div th:if="${#fields.hasErrors('mother.firstName') or #fields.hasErrors('mother.lastName')}" class="form-row clearfix has-error">
        <div class="help-block small">
            <ul>
                <li th:each="err : ${#fields.errors('mother.firstName')}" th:text="${err}"></li>
                <li th:each="err : ${#fields.errors('mother.lastName')}" th:text="${err}"></li>
            </ul>
        </div>
    </div>
</div>

Parent类使用标准命名约定,具有firstName和lastName以及getter / setter。这一切都按预期工作 - 验证,显示,绑定。

所以我试图通过将签名更改为 th:fragment =&#34; name(parent,parentType)&#34; 并替换&#34;母亲&#34;实例到父母&#34;例如:

<div class="form-group" th:fragment="name(parent, parentType)">
    <div class="form-row clearfix">
        <div th:classappend="${#fields.hasErrors('parent.firstName') or #fields.hasErrors('parent.lastName')} ? has-error : ''">
            <label class="control-label col-xs-12" th:classappend="${#fields.hasErrors('parent.firstName') or #fields.hasErrors('parent.lastName')} ? has-error : ''" th:text="|What is the ${parentType}'s name?|"></label>
        </div>
        <div class="col-sm-11 col-sm-offset-1 col-xs-12">
            <div class="form-row form-group">
                <div th:classappend="${#fields.hasErrors('parent.firstName')} ? has-error : ''" class="col-xs-12 col-sm-6">
                    <div class="input-group">
                        <label th:for="parent.firstName" class="control-label">First&nbsp;</label>
                        <input type="text" th:field="*{parent.firstName}" th:value="*{parent.firstName}" class="form-control"/>
                    </div> 
                </div>
                <div th:classappend="${#fields.hasErrors('parent.lastName')} ? has-error : ''" class="col-xs-12 col-sm-6">
                    <div class="input-group">
                        <label th:for="parent.lastName" class="control-label">Last&nbsp;</label>
                        <input type="text" th:field="*{parent.lastName}" th:value="*{parent.lastName}" class="form-control"/>
                    </div> 
                </div>
            </div>
        </div>
    </div>
    <div th:if="${#fields.hasErrors('parent.firstName') or #fields.hasErrors('parent.lastName')}" class="form-row clearfix has-error">
        <div class="help-block small">
            <ul>
                <li th:each="err : ${#fields.errors('parent.firstName')}" th:text="${err}"></li>
                <li th:each="err : ${#fields.errors('parent.lastName')}" th:text="${err}"></li>
            </ul>
        </div>
    </div>
</div>

父母&#34;是对象的实例和&#34; parentType&#34;只是父类型的字符串值(例如&#34;母亲&#34;或&#34;父亲&#34;)用于显示目的。

<div th:replace="fragments/survey/mother::name(*{mother}, 'mother')"></div>

我以这种方式尝试时得到的错误:

Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "#fields.hasErrors('parent.firstName') or #fields.hasErrors('parent.lastName')" (template: "fragments/survey/mother" - line 7, col 18)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#fields.hasErrors('parent.firstName') or #fields.hasErrors('parent.lastName')" (template: "fragments/survey/mother" - line 7, col 18)

如何以通用方式引用#fields.hasErrors()方法中的字段?

Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'parent' of bean class [g.s.m.ParentForm]: Bean property 'parent' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

显然,bean属性被命名为#34; mother&#34;和#34;父亲,&#34;那么如何让这个通用片段绑定到&#34;母亲&#34;和父亲&#34;而不是父母?&#34;

1 个答案:

答案 0 :(得分:1)

所以,首先你必须意识到,对于像th:field#fields.hasErrors()这样的东西,字符串结果必须匹配支持对象的完整路径(而不是像{{1}这样的局部变量}})。您不能使用parent,因为ParentForm没有getParent()。getFirstName()。为此,您必须使用preprocessing

您需要的只是对象名称,而不是将对象传递给片段。 (在您的情况下,由于parentType已经有母亲或父亲,我将在示例中使用它们。)进行这些更改后,您的字段应如下所示:

*{parent.firstName}

另外,附注......如果您使用<div th:classappend="${#fields.hasErrors(parentType + '.firstName')} ? has-error : ''" class="col-xs-12 col-sm-6"> <div class="input-group"> <label th:for="${parentType + '.firstName'}" class="control-label">First&nbsp;</label> <input type="text" th:field="*{__${parentType}__.firstName}" class="form-control"/> </div> </div> <div th:classappend="${#fields.hasErrors(parentType + '.lastName')} ? has-error : ''" class="col-xs-12 col-sm-6"> <div class="input-group"> <label th:for="${parentType + '.lastName'}" class="control-label">Last&nbsp;</label> <input type="text" th:field="*{__${parentType}__.firstName}" class="form-control"/> </div> </div> ,则不必使用th:fieldth:value为你做到了。