2014-11-27 4 views
2

Я пытаюсь создать форму thymeleaf для обновления всего пару атрибутов основы объекта:Обновления формы: Spring MVC + thymeleaf

@RequestMapping(value = "/jobs/{id}", method = RequestMethod.GET) 
public ModelAndView update(@PathVariable Integer id) { 
    ModelAndView mav = new ModelAndView("updateJob.html"); 
    JobDescription updateJob = jobDescriptionService.findByID(id); 
    mav.addObject("updateJob", updateJob); 
    return mav; 
} 

@RequestMapping(value = "/jobs/{id}", method = RequestMethod.PUT) 
public String saveUpdate(@PathVariable Integer id, @ModelAttribute("updateJob") JobDescription updateJob) { 
    jobDescriptionService.update(updateJob); 
    return "redirect:/jobs/" + id; 
} 


<form th:action="@{'/jobs/'+ ${updateJob.id}}" th:object="${updateJob}" th:method="PUT"> 
    <table> 
     <tr> 
      <td><label>Description</label></td> 
      <td><input type="text" th:field="*{description}" /></td> 
     </tr> 
     <tr> 
      <td><label>Deadline</label></td> 
      <td><input type="text" th:field="*{deadline}" /></td> 
     </tr> 
     <tr> 
      <td></td> 
      <td><button type="submit">Update</button></td> 
     </tr> 
    </table> 
</form> 

Проблема заключается в том, что объект задания имеет несколько других атрибуты (например, id, createdDate и т. д.), которые я не хочу обновлять. Однако, когда я нажимаю кнопку отправки формы обновления, объект, созданный в методе saveUpdate, имеет те атрибуты, которые установлены в значение null (если я не задал их в скрытых полях внутри формы). Есть ли другой способ сохранить их?

ответ

-4
var editOptions = { 
    url: '/Admin/EditPost', 
    editCaption: 'Edit Post', 
    processData: "Saving...", 
    width: 900, 
    closeAfterEdit: true, 
    closeOnEscape: true, 
    afterclickPgButtons: afterclickPgButtons, 
    afterShowForm: afterShowForm,   
    onClose: onClose, 
    afterSubmit: JustBlog.GridManager.afterSubmitHandler, 
    beforeSubmit: beforeSubmitHandler 
}; 

$(gridName).navGrid(pagerName, 
{ 
    cloneToTop: true, 
    search: false 
}, 
editOptions, addOptions, {}); 
+2

Скважины кода не являются буено. Объясните, как это устраняет проблему. Кроме того, я уверен, что OP использует Java, а не JavaScript. – royhowie

1

Самый безопасный способ сделать это, чтобы загрузить исходный объект задания по идентификатору, и установить новые значения на него, а затем обновить его ... Что-то вроде:

JobDescription originalJob = jobDescriptionService.findById(updateJob.getId()); 

originalJob.setParamForUpdate(updateJob.getParamForUpdate()); 
originalJob.setAnotherParamForUpdate(updateJob.getAnotherParamForUpdate()); 

jobDescriptionService.update(originalJob); 

И это сэкономит все данные, которые вы хотите сохранить неизменными ...

+0

как вы обнаруживаете, какие поля изменились? – skgemini

+0

Сравнивая его с исходным значением. Если у вас их несколько, конечно ... Если у вас есть больше, чем позволяет сказать 10 полей, вы можете написать обобщенный метод, который принимает два объекта и сравнивает их для изменений с помощью Reflection. Таким образом, его можно снова использовать повторно. Вот пример http://pastebin.com/4zrXFhic, используя отражение. Измените его в соответствии с вашими потребностями –

0

у меня такая же проблема, как вы, так что я построил мое собственное решение

1- Вам нужны два действия на контроллере: вид (GET) и действие (POST)

@GetMapping("/user/edit/{userId}") 
public ModelAndView editUserView(@PathVariable Long userId) throws NotFoundException { 

    User user = this.userService.load(userId); 

    if (user == null) { 
     throw new NotFoundException("Not found user with ID " + userId); 
    } 

    ModelAndView modelAndView = new ModelAndView(); 

    modelAndView.setViewName("user.edit"); 
    modelAndView.addObject("user", user); 

    return modelAndView; 
} 

@PostMapping("/user/edit/{userId}") 
public ModelAndView editUserAction(HttpServletRequest request, @PathVariable Long userId, @Validated(User.ValidationUpdate.class) User userView, 
     BindingResult bindingResult) throws Exception { 

    User user = this.userService.load(userId); 

    if (user == null) { 
     throw new NotFoundException("Not found user with ID " + userId); 
    } 

    ModelAndView modelAndView = new ModelAndView(); 
    if (bindingResult.hasErrors()) {    
     modelAndView.setViewName("user.edit"); 
     modelAndView.addObject("user", userView); 

     return modelAndView; 
    } 

    Form.bind(request, userView, user); 

    this.userService.update(user); 

    modelAndView.setViewName("redirect:/admin/user"); 

    return modelAndView; 
} 

2- Один вида с отображением ошибок (Веррите важно: добавить скрытый ввод отправить идентификатор для проверки)

<fieldset th:if="${#fields.hasErrors('${user.*}')}" class="text-warning"> 
    <legend>Some errors appeared !</legend> 
    <ul> 
     <li th:each="err : ${#fields.errors('user.*')}" th:text="${err}"></li> 
    </ul> 
</fieldset> 

<form action="#" th:action="@{/admin/user/edit/{id}(id=${user.id})}" th:object="${user}" method="post"> 
     <div th:class="${#fields.hasErrors('firstName')} ? 'form-group has-error' : 'form-group'"> 
      <label class="control-label" for="firstName">First Name <span class="required">*</span></label> 
      <input type="text" th:field="*{firstName}" required="required"> 
     </div> 
     ... 
    <input type="hidden" th:field="*{id}"> 
</form> 

3- Для моего примера, я написал класс FormUtility, чтобы объединить два объекта:

public static List<String> bind(HttpServletRequest request, Object viewObject, Object daoObject) throws Exception { 

    if (viewObject.getClass() != daoObject.getClass()) { 
     throw new Exception("View object and dao object must have same type (class) !"); 
    } 

    List<String> errorsField = new ArrayList<String>(); 

    // set field value 
    for (Entry<String, String[]> parameter : request.getParameterMap().entrySet()) { 

     // build setter/getter method 
     String setMethodName = "set" + parameter.getKey().substring(0, 1).toUpperCase() 
       + parameter.getKey().substring(1); 
     String getMethodName = "get" + parameter.getKey().substring(0, 1).toUpperCase() 
       + parameter.getKey().substring(1); 

     try { 
      Method getMethod = daoObject.getClass().getMethod(getMethodName); 
      Method setMethod = daoObject.getClass().getMethod(setMethodName, getMethod.getReturnType()); 
      setMethod.invoke(daoObject, getMethod.invoke(viewObject)); 
     } 
     catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException 
       | InvocationTargetException exception) { 
      errorsField.add(parameter.getKey()); 
     } 
    } 

    return errorsField; 
} 

Надеюсь, это поможет вам.

Смежные вопросы