2012-06-12 68 views
0

我使用Spring AutoPopulatingList和JQuery創建了一個動態表單。追加工作就像一個魅力,新的項目被創建並堅持到數據庫。問題在於刪除:無論刪除瀏覽器端的元素,我的更新方法都會獲取完整列表。從Spring的AutoPopulatingList中刪除項目

控制器的更新方法是這麼簡單

@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刪除語言1 一個.remove()方法):

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

所以從通信方面看起來不錯,但是從@ModelAttribute(檢索在UpdateUser兩個方法的用戶「用戶」),仍然有三個語言元素,所有有效(即不爲空)。 有什麼建議嗎? 我使用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

嘗試使用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)); 

希望這可以幫助你。乾杯。

+0

它沒有幫助不幸的是......我的意思是,結果是一樣的,我不管刪除表單字段鑑於在控制器我更新的方法我還是有着充沛列表...有以其他方式... –

+0

我不知道你是如何做到這一點在jsp中,但我使用jquery並將它添加到具有由Spring呈現的名稱和ID的jsp中添加html控件。它的工作完美。 –

+0

更新了包含客戶端JavaScript的問題 –

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(「更新」)解決了這個問題。 現在從窗體中刪除的對象實際上是空的。

現在,我堅持用之前從列表中刪除它們掙扎,因爲

removeAll(Collections.singleton(null)); 

似乎並沒有工作。

+0

我正在使用這個:'removeAll(Collections.singletonList(null));'' – Enrichman

0

當你使用jquery從視圖中刪除列表元素標記時,它只能將新值綁定到那個元素上。但它不會從控制器的列表中刪除元素。

爲了清楚起見,這裏是jsp + spring如何將數據綁定到列表元素。爲了綁定列表中的第i個元素,它將調用list.get(i).set(newVal)。所以當你從視圖中刪除第i個元素時,沒有任何東西獲得綁定,但是同時第i個元素也不會被刪除。

對於刪除,您可能會在每次刪除元素並從控制器的列表中刪除該元素時發送一個jax請求。用戶「日本鬼子T」呈現

0

Soluton不爲我工作之一:

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

我紅可能的解決方案。這裏是清單:

  • 取消對服務器端的所有物品通過AJAX
  • 從請求
  • 更新服務器狀態綁定值

的「不透明」解決方案,我會嘗試之前是隱藏的HTML元素,而不是刪除和清除輸入值,然後在服務器端可以實現忽略「空」記錄的功能。例如:

interface Removeable { 
boolean isEmpty(); 
} 

(Collection<Removeable>)myCollection.removeIf(e -> e.isEmpty())