Spring 3 MVC:动态表单中的一对多(在创建更新时添加删除)

Spring 3 MVC:动态表单中的一对多(在创建更新时添加删除),第1张

Spring 3 MVC:动态表单中的一对多(在创建/更新时添加/删除)

这一点在网络上仍然很混乱并且不清楚,因此这是我解决问题的方法。此解决方案可能不是最优化的解决方案,但在 创建和更新实体时可以使用。

理论
  1. 对于应该动态管理的一对多关系,请使用a

    List
    代替a
    Set

  2. 将初始化

    List
    AutoPopulatingList
    。这是一个懒惰列表,允许动态 添加 元素

  3. 添加一个属性

    remove
    int
    ,以你的子实体。这将充当布尔标志的一部分,并且在动态 删除 元素时将很有用。

  4. 在发布形式,坚持只有具有该标志的元素

    remove
    0
    (即
    false
    )。

实践

一个完整的例子:一个雇主有很多雇员,一个雇员有一个雇主。

实体:

Employer.java

@Entity@Table(name = "employer")public class Employer    private Integer id;    private String firstname;    private String lastname;    private String company;    private List<Employee> employees; // one-to-many    }

Employee.java

@Entity@Table(name = "employee")public class Employee {    private Integer id;    @Transient // means "not a DB field"    private Integer remove; // boolean flag    private String firstname;    private String lastname;    private Employer employer; // many-to-one    }
控制器:

EmployerController.java

@Controller@RequestMapping("employer")public class EmployerController {    // Manage dynamically added or removed employees    private List<Employee> manageEmployees(Employer employer) {        // Store the employees which shouldn't be persisted        List<Employee> employees2remove = new ArrayList<Employee>();        if (employer.getEmployees() != null) { for (Iterator<Employee> i = employer.getEmployees().iterator(); i.hasNext();) {     Employee employee = i.next();     // If the remove flag is true, remove the employee from the list     if (employee.getRemove() == 1) {         employees2remove.add(employee);         i.remove();     // Otherwise, perform the links     } else {         employee.setEmployer(employer);     } }        }        return employees2remove;    }    // -- Creating a new employer ----------    @RequestMapping(value = "create", method = RequestMethod.GET)    public String create(@ModelAttribute Employer employer, Model model) {        // Should init the AutoPopulatingList        return create(employer, model, true);    }    private String create(Employer employer, Model model, boolean init) {        if (init) { // Init the AutoPopulatingList employer.setEmployees(new AutoPopulatingList<Employee>(Employee.class));        }        model.addAttribute("type", "create");        return "employer/edit";    }    @RequestMapping(value = "create", method = RequestMethod.POST)    public String create(@Valid @ModelAttribute Employer employer, BindingResult bindingResult, Model model) {        if (bindingResult.hasErrors()) { // Should not re-init the AutoPopulatingList return create(employer, model, false);        }        // Call the private method        manageEmployees(employer);        // Persist the employer        employerService.save(employer);        return "redirect:employer/show/" + employer.getId();    }    // -- Updating an existing employer ----------    @RequestMapping(value = "update/{pk}", method = RequestMethod.GET)    public String update(@PathVariable Integer pk, @ModelAttribute Employer employer, Model model) {        // Add your own getEmployerById(pk)        model.addAttribute("type", "update");        return "employer/edit";    }    @RequestMapping(value = "update/{pk}", method = RequestMethod.POST)    public String update(@PathVariable Integer pk, @Valid @ModelAttribute Employer employer, BindingResult bindingResult, Model model) {        // Add your own getEmployerById(pk)        if (bindingResult.hasErrors()) { return update(pk, employer, model);        }        List<Employee> employees2remove = manageEmployees(employer);        // First, save the employer        employerService.update(employer);        // Then, delete the previously linked employees which should be now removed        for (Employee employee : employees2remove) { if (employee.getId() != null) {     employeeService.delete(employee); }        }        return "redirect:employer/show/" + employer.getId();    }    // -- Show an existing employer ----------    @RequestMapping(value = "show/{pk}", method = RequestMethod.GET)    public String show(@PathVariable Integer pk, @ModelAttribute Employer employer) {        // Add your own getEmployerById(pk)        return "employer/show";    }}
视图:

employer/edit.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%><%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE HTML><html><head>    <title>Edit</title>    <style type="text/css">.hidden {display: none;}</style>    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>    <script type="text/javascript">    $(function() {        // Start indexing at the size of the current list        var index = ${fn:length(employer.employees)};        // Add a new Employee        $("#add").off("click").on("click", function() { $(this).before(function() {     var html = '<div id="employees' + index + '.wrapper" >';   html += '<input type="text" id="employees' + index + '.firstname" name="employees[' + index + '].firstname" />';     html += '<input type="text" id="employees' + index + '.lastname" name="employees[' + index + '].lastname" />';     html += '<input type="hidden" id="employees' + index + '.remove" name="employees[' + index + '].remove" value="0" />';     html += '<a href="#"  data-index="' + index + '">remove</a>';   html += "</div>";     return html; }); $("#employees" + index + "\.wrapper").show(); index++; return false;        });        // Remove an Employee        $("a.employees\.remove").off("click").on("click", function() { var index2remove = $(this).data("index"); $("#employees" + index2remove + "\.wrapper").hide(); $("#employees" + index2remove + "\.remove").val("1"); return false;        });    });    </script></head><body>    <c:choose>        <c:when test="${type eq 'create'}"><c:set var="actionUrl" value="employer/create" /></c:when>        <c:otherwise><c:set var="actionUrl" value="employer/update/${employer.id}" /></c:otherwise>    </c:choose>    <form:form action="${actionUrl}" modelAttribute="employer" method="POST" name="employer">        <form:hidden path="id" />        <table> <tr>     <td><form:label path="firstname">Firstname</form:label></td>     <td><form:input path="firstname" /><form:errors path="firstname" /></td> </tr> <tr>     <td><form:label path="lastname">Lastname</form:label></td>     <td><form:input path="lastname" /><form:errors path="lastname" /></td> </tr> <tr>     <td><form:label path="company">company</form:label></td>     <td><form:input path="company" /><form:errors path="company" /></td> </tr> <tr>     <td>Employees</td>     <td>         <c:forEach items="${employer.employees}" varStatus="loop">  <!-- Add a wrapping div -->  <c:choose>      <c:when test="${employer.employees[loop.index].remove eq 1}">          <div id="employees${loop.index}.wrapper" >      </c:when>      <c:otherwise>          <div id="employees${loop.index}.wrapper">      </c:otherwise>  </c:choose>      <!-- Generate the fields -->      <form:input path="employees[${loop.index}].firstname" />      <form:input path="employees[${loop.index}].lastname" />      <!-- Add the remove flag -->      <c:choose>          <c:when test="${employees[loop.index].remove eq 1}"><c:set var="hiddenValue" value="1" /></c:when>          <c:otherwise><c:set var="hiddenValue" value="0" /></c:otherwise>      </c:choose>      <form:hidden path="employees[${loop.index}].remove" value="${hiddenValue}" />      <!-- Add a link to remove the Employee -->      <a href="#"  data-index="${loop.index}">remove</a>  </div>         </c:forEach>         <button id="add" type="button">add</button>     </td> </tr>        </table>        <button type="submit">OK</button>    </form:form></body></html>

希望能有所帮助

:)



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4991823.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-14

发表评论

登录后才能评论

评论列表(0条)

保存