【问题标题】:Thymeleaf nested object form binding not generating good input nameThymeleaf 嵌套对象表单绑定未生成良好的输入名称
【发布时间】:2015-09-11 14:15:34
【问题描述】:

我有以下对象结构:

public class A{

    private int id;
    private B objB;

    public A(){}

    --- setters & getters ---
}

这是我的B班:

public class B{

    private int id;
    private int test;

    public B(){}

    --- setters & getters ---
}

我将一个 A 对象传递给我的视图,我想为我的 B 对象创建一个表单:

<form id="bForm" th:object=${A.objB} th:action="@{/save}">
    <input th:field=*{test} type="text"/>
</form>

但是上面的代码会起作用,它会生成这样的输入名称:objB.test,为此我的控制器无法将其绑定到 B 对象。

这是我控制器中的接收方法:

    @RequestMapping("/save")
    @ResponseBody
    public String setB(@ModelAttribute("bForm") B b, BindingResult result) {
        aService.setB(b);
        return "...";
    }

我如何设置 Thymeleaf 来命名我的字段而不使用前缀而不是:objB.test 只是 test

非常感谢任何帮助。

【问题讨论】:

    标签: spring spring-mvc thymeleaf


    【解决方案1】:

    根据thymeleaf-spring docs

    表单标签中th:object 属性的值必须是变量表达式 (${...}),仅指定模型属性的名称,而无需属性导航。这意味着像 ${seedStarter} 这样的表达式是有效的,但 ${seedStarter.data} 是无效的。

    尝试在表单前使用th:with 属性来分配A.objB 变量,因此,请避免在th:object 属性中使用属性导航。

    似乎要遵守此要求,您必须在处理初始表单呈现的 Spring 控制器的处理程序方法中设置一个附加模型属性。因此,鉴于您在代码的某些部分中已经有类似的内容:

    model.addAttribute("A", new A());
    

    添加另一行:

    model.addAttribute("bForm", new B());
    

    请记住,模型属性名称应与您在问题中发布的提交请求处理程序中的 @ModelAttribute 注释中设置的名称保持一致。

    【讨论】:

    • 感谢您的帮助。但我认为在这种情况下我指的不是财产。我指的是一个具体的模型,那个模型是 B 类。不幸的是 是一个 jsp 标签,所以我不能在 html 文件中使用它。我所做的尝试是用 th:with 创建局部变量,但这也不能解决它。
    • 当然你是对的,我的意思是th:with 属性,但是以某种方式混淆了它们,哈哈(我现在编辑了答案)。但是既然你已经试过了,结果和不使用th:with一样吗?
    • 这里是我的示例:&lt;div th:with="objB = ${A.objB}"&gt; &lt;form method="post" th:object="${objB}"&gt; 这会给我一个错误:java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'objB' available as request attribute
    • 有趣...请查看我的更新答案(抱歉最初误导您)。
    • 所以基本上不可能解决我想做的事情。很遗憾,但感谢您的帮助。
    【解决方案2】:

    也许是一个迟到的答案,但如果 objectB 是 A 的内部对象,那么您可以将字段绑定到 B 作为 A 的内部对象并在控制器中处理 objectA。

    它看起来像这样,但在我的情况下,提示是此处包含对象的 Arraylist:

        <th:block th:each="pr, stat : ${taskExecution.prompt}">
          <input type="hidden" id="hiddenName" th:field="*{prompt[__${stat.index}__].name}" th:value="${pr.name}">
          <input type="hidden" id="hiddenValue" th:field="*{prompt[__${stat.index}__].value}" th:value="${pr.value}">
        </th:block>
    

    【讨论】:

      猜你喜欢
      • 2019-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      • 2021-09-06
      • 2017-05-27
      • 2021-08-15
      • 2016-02-17
      相关资源
      最近更新 更多