我使用 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(); });
};