我使用Spring AutoPopulatingList和JQuery创建了一个动态表单。添加类似于魅力,新项目被创建并持久保存到数据库中。问题是删除:我的更新方法总是获取完整列表,无论删除浏览器端的元素。
Controller的更新方法很简单
@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<Language> 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”)检索的用户仍然有三个语言元素,全部有效(即不为空)。 有什么建议? 我正在使用Spring 3.1.1和JQuery 1.7.2,如果这是相关的。
编辑: 添加/删除字段的客户端代码如下:
$.addLanguage = function() {
var newLanguage = $('<input type="text" id="languages' + languagesCounter + '.code" name="languages[' + languagesCounter + '].code" class="langIdentifier"/>' +
'<select id="languages' + languagesCounter + '.level" name="languages[' + languagesCounter + '].level" class="langSelect">' +
'<option value="Basic">Basic</option>' +
'<option value="Intermediate">Intermediate</option>' +
'<option value="Fluent">Fluent</option>' +
'<option value="Native">Native</option>' +
'</select>' +
'<input type="button" id="remove' + languagesCounter + '" onclick="$.removeLanguage(' + languagesCounter + ')"' +
'name="Remove" value="Remove" class="removeButton"/>' +
'<br/>');
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(); });
};
答案 0 :(得分:0)
尝试使用 LazyList 而不是 AutoPopulatingList 。我正在使用它向html添加动态内容并将数据返回到模型属性对象中。下面是我用来创建列表的代码。
private List<OperationParameters> operationParameterses = LazyList.decorate(new ArrayList<OperationParameters>(), FactoryUtils.instantiateFactory(OperationParameters.class));
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="operations")
public List<OperationParameters> getOperationParameterses() {
return this.operationParameterses;
}
public void setOperationParameterses(List<OperationParameters> operationParameterses) {
this.operationParameterses = operationParameterses;
}
在控制器中,当我获取模型属性中填充的列表时,我首先检查列表中的空数据,然后使用以下代码将其删除,然后在数据库中保留。否则,它会尝试在数据库中插入空数据。
operations.getOperationParameterses().removeAll(Collections.singleton(null));
希望这会对你有所帮助。欢呼声。
答案 1 :(得分:0)
回答我自己的问题(或许可以省一些人头疼):
我已经
了@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));
似乎不起作用。
答案 2 :(得分:0)
当您使用jquery从视图中删除列表元素标记时,它只会阻止将新值绑定到该元素。但它不会从控制器列表中删除元素。
为了清楚起见,jsp + spring将如何将数据绑定到list元素。对于绑定列表的第i个元素,它将调用list.get(i).set(newVal)。所以当你从视图中删除第i个元素时,没有任何东西会被绑定,但同时我的元素也不会被删除。
对于删除,您可以在每次删除元素时发送ajax请求,并从控制器中的列表中删除该元素。
答案 3 :(得分:0)
用户“Japs T”提出的Soluton对我来说也不起作用:
operations.getOperationParameterses().removeAll(Collections.singleton(null));
我对可能的解决方案很感兴趣。这是清单:
我会尝试的“不透明”解决方案是隐藏HTML元素而不是删除和清除输入中的值,然后在服务器端,您可以实现忽略“空”记录的功能。例如:
interface Removeable {
boolean isEmpty();
}
(Collection<Removeable>)myCollection.removeIf(e -> e.isEmpty())