从Spring的AutoPopulatingList中删除项目

我使用Spring AutoPopulatingList和JQuery创建了一个动态表单。 添加类似于魅力,新项目被创建并持久保存到数据库中。 问题是删除:我的更新方法总是获取完整列表,无论删除浏览器端的元素。

控制器的更新方法很简单

@RequestMapping(value = "/user/{id}", method = RequestMethod.POST) @ResponseBody public String updateUser(@PathVariable("id") int id, @ModelAttribute("user") User user, HttpServletRequest request) { userService.update(user); return messageSource.getMessage("user.data_updated", null, request.getLocale()); } 

用户POJO实现如下

 @Entity public class User implements Serializable { ... @OneToMany(targetEntity = Language.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List languages = new AutoPopulatingList(Language.class); ... } 

发送到我的控制器的POST请求看起来像那样(另外,添加了语言2):

 languages[0].code:pl languages[0].level:Fluent languages[1].code:de languages[1].level:Native languages[2].code:cc languages[2].level:Intermediate 

和删除(使用JQuery .remove()方法删除语言1):

 languages[0].code:pl languages[0].level:Fluent languages[2].code:cc languages[2].level:Intermediate 

所以从通信端看起来还行,但是在updateUser方法中从@ModelAttribute(“user”)检索的用户仍然有三个语言元素,都是有效的(不是null)。 有什么建议? 我正在使用Spring 3.1.1和JQuery 1.7.2,如果这是相关的。

编辑:添加/删除字段的客户端代码如下:

 $.addLanguage = function() { var newLanguage = $('' + '' + 'Basic' + 'Intermediate' + 'Fluent' + 'Native' + '' + '' + '
'); languagesCounter++; newLanguage.insertBefore($("#add")); }

并删除:

 $.removeLanguage = function(languageId) { var languageField = '#languages' + languageId + '\\.code'; var levelField = '#languages' + languageId + '\\.level'; var removeButton = '#remove' + languageId; $(languageField).fadeOut(250, function() { $(this).remove(); }); $(levelField).fadeOut(250, function() { $(this).remove(); }); $(removeButton).fadeOut(250, function() { $(this).remove(); }); }; 

尝试使用LazyList而不是AutoPopulatingList 。 我正在使用它向html添加动态内容并将数据返回到模型属性对象中。 下面是我用来创建列表的代码。

  private List operationParameterses = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(OperationParameters.class)); @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="operations") public List getOperationParameterses() { return this.operationParameterses; } public void setOperationParameterses(List operationParameterses) { this.operationParameterses = operationParameterses; } 

在控制器中,当我获取模型属性中填充的列表时,我首先检查列表中的空数据,然后使用以下代码将其删除,然后在数据库中保留。 否则,它会尝试在数据库中插入空数据。

 operations.getOperationParameterses().removeAll(Collections.singleton(null)); 

希望这对你有所帮助。 干杯。

回答我自己的问题(也许会让人有些头疼):

我有过

 @ModelAttribute("user") public User getUserById(@PathVariable("id") int id) { logger.fine("Getting user for id: " + id); return userService.findById(id); } 

在GET中填充模型,和

 @RequestMapping(value = "/user/{id}", method = RequestMethod.POST) @ResponseBody public String updateUser(@PathVariable("id") int id, @ModelAttribute("user") User user, HttpServletRequest request) { userService.update(user); return messageSource.getMessage("user.data_updated", null, request.getLocale()); } 

更新用户。 现在整个问题出现在POST处理程序中的@ModelAttribute中 – 它不能与预填充代码中的密钥名称相同。 将其更改为@ModelAttribute(“updated”)解决了这个问题。 现在从表单中删除的对象确实是null。

现在我正在努力将它们从列表中删除,然后坚持下去,因为

 removeAll(Collections.singleton(null)); 

似乎没有用。

当您使用jquery从视图中删除列表元素标记时,它只会阻止将新值绑定到该元素。 但它不会从控制器列表中删除元素。

为清楚起见,jsp + spring将如何将数据绑定到list元素。 对于绑定列表的第i个元素,它将调用list.get(i).set(newVal)。 因此,当您从视图中删除第i个元素时,没有任何内容可以绑定,但同时我也不会删除元素。

对于删除,您可以在每次删除元素时发送ajax请求,并从控制器中的列表中删除该元素。

用户“Japs T”提出的Soluton对我来说也不起作用:

 operations.getOperationParameterses().removeAll(Collections.singleton(null)); 

我对可能的解决方案感兴趣 这是清单:

  • 在从请求绑定值之前删除服务器端的所有项目
  • 通过AJAX更新服务器状态

我会尝试的“不透明”解决方案是隐藏HTML元素而不是删除和清除输入中的值,然后在服务器端,您可以实现忽略“空”记录的function。 例如:

 interface Removeable { boolean isEmpty(); } (Collection)myCollection.removeIf(e -> e.isEmpty())