Spring ajax 更新后不再识别模型属性
Spring modelattribute not recognized anymore after ajax update
我曾多次遇到以下问题:
我使用控制器将 dto 绑定到 html 表单(通过 thymeleaf)。 请注意名为“invoiceDto”的模型
@RequestMapping(value = {"/create"}, method = RequestMethod.GET)
public String create(Locale locale, Model model) throws Exception {
final String login = this.getAuthentication().getCurrentApplicationUser();
if (login == null || login.isEmpty())
throw new Exception(this.getMessageSource().getMessage("label.findError", null, locale));
final Future<Setting> setting = settingService.findFirst();
final Future<ApplicationUserContactProjection> applicationUserContactProjection = applicationUserService.findByLogin(login);
while (!setting.isDone() && !applicationUserContactProjection.isDone()) {
Thread.sleep(100);
}
if (setting.get() == null || applicationUserContactProjection.get() == null)
throw new Exception(this.getMessageSource().getMessage("label.error.findError",
null, locale));
model.addAttribute("invoiceDto", new InvoiceDto(setting.get(), applicationUserContactProjection.get()));
model.addAttribute("message", this.getMessageSource().getMessage("label.navigation.invoiceCreation", null, locale));
return "invoice/create";
}
我有一个 html 表单(thymeleaf 生成),我在其中使用上面的 Java pojo dto 和给定的模型属性名称来填充我的输入字段。这是它的节选。 重要的部分是 ID 为“invoiceLineItems”的 div,其中 thymeleaf 将其子项 div 替换为 lineItems 片段:
<form action="#" th:action="@{/invoice/newinvoice}" th:object="${invoiceDto}" role="form" method="post"
class="form-signin" id="editInvoiceForm"
accept-charset="utf-8">
<div id="invoiceLineItems"><div th:replace="invoice/items :: lineItems"></div></form>
该片段包含以下内容 - 摘录:
<td>
<input type="text"
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
readonly
class="form-control" disabled
id="lineItemTotalPrice"/>
</td>
给定 pojo 的摘录:
public class InvoiceDto implements Serializable {
private Invoice invoice;
private List<LineItem> items;
我这样访问列表:
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
问题:
我可以通过 Ajax 动态添加项目。我序列化整个表单(出于方便的原因)并调用控制器方法:
@RequestMapping(value = {"/newlineitem"}, method = RequestMethod.POST)
public String newLineItem(@ModelAttribute("invoiceDto") InvoiceDto invoiceDto,
Model model)
throws Exception {
invoiceDto.addItem(new LineItem());
final Future<InvoiceDto> calculatedInvoiceDto = invoiceService.calculateInvoice(invoiceDto);
while (!calculatedInvoiceDto.isDone()) {
Thread.sleep(100);
}
model.addAttribute("invoiceDto", calculatedInvoiceDto.get());
return "invoice/dynamicitems :: lineItems";
}
如您所见,我让 thymeleaf 渲染一个特殊视图,因为 Ajax 成功后 spring 无法正确设置模型属性。
简而言之:Ajax Returns分部视图后,下面会抛出异常:
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
虽然这有效 - 请注意前缀 invoiceDto:
th:field="*{invoiceDto.items[__${index.index}__].lineItemTotalPrice}"
问题:
这里有什么问题?
为什么我必须在部分 Ajax 更新后加上模型属性的名称前缀,而在第一个 运行 中我不需要?
感谢您的帮助!
编辑:
对于我的分享,如果页面被 ajax 调用部分更新(到另一个 spring 控制器,修改invoiceDto) 通过部分百里香 html.
所以在控制器 returns 部分 thymeleaf 视图之后,我必须访问其前缀为“invoiceDto”的字段,就好像没有 invoiceDto 属性一样。
再次感谢您的帮助!
更新
由于在这方面没有进展,我提出了百里香叶问题:
https://github.com/thymeleaf/thymeleaf/issues/795
尽管如此,我认为这是一个 spring 问题,因为我与 JSP.
的结果相同
了解此问题的存储库
https://mygit.th-deg.de/tlang/thymefail
如果我对您的问题的理解正确,那么您是在没有活动对象时尝试使用 *{}
表示法。当 ajax 方法 return 只是“lineItems”片段时,Thymeleaf 无法知道它属于上面带有 th:object
的表单。
我想最好的解决方案是 return 整个表单,然后在 js 中提取 lineItems。
或者干脆去掉 th:object
(仅当你想显示验证错误恕我直言时才方便)。
我曾多次遇到以下问题:
我使用控制器将 dto 绑定到 html 表单(通过 thymeleaf)。 请注意名为“invoiceDto”的模型
@RequestMapping(value = {"/create"}, method = RequestMethod.GET)
public String create(Locale locale, Model model) throws Exception {
final String login = this.getAuthentication().getCurrentApplicationUser();
if (login == null || login.isEmpty())
throw new Exception(this.getMessageSource().getMessage("label.findError", null, locale));
final Future<Setting> setting = settingService.findFirst();
final Future<ApplicationUserContactProjection> applicationUserContactProjection = applicationUserService.findByLogin(login);
while (!setting.isDone() && !applicationUserContactProjection.isDone()) {
Thread.sleep(100);
}
if (setting.get() == null || applicationUserContactProjection.get() == null)
throw new Exception(this.getMessageSource().getMessage("label.error.findError",
null, locale));
model.addAttribute("invoiceDto", new InvoiceDto(setting.get(), applicationUserContactProjection.get()));
model.addAttribute("message", this.getMessageSource().getMessage("label.navigation.invoiceCreation", null, locale));
return "invoice/create";
}
我有一个 html 表单(thymeleaf 生成),我在其中使用上面的 Java pojo dto 和给定的模型属性名称来填充我的输入字段。这是它的节选。 重要的部分是 ID 为“invoiceLineItems”的 div,其中 thymeleaf 将其子项 div 替换为 lineItems 片段:
<form action="#" th:action="@{/invoice/newinvoice}" th:object="${invoiceDto}" role="form" method="post"
class="form-signin" id="editInvoiceForm"
accept-charset="utf-8">
<div id="invoiceLineItems"><div th:replace="invoice/items :: lineItems"></div></form>
该片段包含以下内容 - 摘录:
<td>
<input type="text"
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
readonly
class="form-control" disabled
id="lineItemTotalPrice"/>
</td>
给定 pojo 的摘录:
public class InvoiceDto implements Serializable {
private Invoice invoice;
private List<LineItem> items;
我这样访问列表:
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
问题:
我可以通过 Ajax 动态添加项目。我序列化整个表单(出于方便的原因)并调用控制器方法:
@RequestMapping(value = {"/newlineitem"}, method = RequestMethod.POST)
public String newLineItem(@ModelAttribute("invoiceDto") InvoiceDto invoiceDto,
Model model)
throws Exception {
invoiceDto.addItem(new LineItem());
final Future<InvoiceDto> calculatedInvoiceDto = invoiceService.calculateInvoice(invoiceDto);
while (!calculatedInvoiceDto.isDone()) {
Thread.sleep(100);
}
model.addAttribute("invoiceDto", calculatedInvoiceDto.get());
return "invoice/dynamicitems :: lineItems";
}
如您所见,我让 thymeleaf 渲染一个特殊视图,因为 Ajax 成功后 spring 无法正确设置模型属性。
简而言之:Ajax Returns分部视图后,下面会抛出异常:
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
虽然这有效 - 请注意前缀 invoiceDto:
th:field="*{invoiceDto.items[__${index.index}__].lineItemTotalPrice}"
问题:
这里有什么问题?
为什么我必须在部分 Ajax 更新后加上模型属性的名称前缀,而在第一个 运行 中我不需要?
感谢您的帮助!
编辑:
对于我的分享,如果页面被 ajax 调用部分更新(到另一个 spring 控制器,修改invoiceDto) 通过部分百里香 html.
所以在控制器 returns 部分 thymeleaf 视图之后,我必须访问其前缀为“invoiceDto”的字段,就好像没有 invoiceDto 属性一样。
再次感谢您的帮助!
更新
由于在这方面没有进展,我提出了百里香叶问题:
https://github.com/thymeleaf/thymeleaf/issues/795
尽管如此,我认为这是一个 spring 问题,因为我与 JSP.
的结果相同了解此问题的存储库
https://mygit.th-deg.de/tlang/thymefail
如果我对您的问题的理解正确,那么您是在没有活动对象时尝试使用 *{}
表示法。当 ajax 方法 return 只是“lineItems”片段时,Thymeleaf 无法知道它属于上面带有 th:object
的表单。
我想最好的解决方案是 return 整个表单,然后在 js 中提取 lineItems。
或者干脆去掉 th:object
(仅当你想显示验证错误恕我直言时才方便)。