2016-07-28 63 views
0

我需要从一个数组中选择值并将其分配给其他数组。使用春季Thymeleaf。不知道如何检索这些选定的值。 我的课:输入阵列Thymeleaf

@Entity 
public class Collaborator { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @NotNull 
    @Size (min=3, max=32) 
    private String name; 

    @NotNull 
    @ManyToOne (cascade = CascadeType.ALL) 
    private Role role; 

    public Collaborator() {}... 

@Entity 
public class Role { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @NotNull 
    @Size(min = 3, max = 99) 
    private String name; 

    public Role() {}.... 

我的控制器:

@RequestMapping("/project_collaborators/{projectId}") 
public String projectCollaborators(@PathVariable Long projectId, Model model) { 
    Project project = mProjectService.findById(projectId); 
    List<Collaborator> allCollaborators = mCollaboratorService.findAll(); 
    List<Collaborator> assignments = new ArrayList<>(); 

    if (project.getRolesNeeded()!=null) { 
     for (int i=0;i<project.getRolesNeeded().size();i++) { 
      assignments.add(new Collaborator("Unassigned", project.getRolesNeeded().get(i))); 
      assignments.get(i).setId((long) 0); 
     } 
    } 

    model.addAttribute("assignments", assignments); 
    model.addAttribute("allCollaborators", allCollaborators); 
    model.addAttribute("project", project); 

    return "project_collaborators"; 
} 

@RequestMapping(value = "/project_collaborators/{projectId}", method = RequestMethod.POST) 
public String projectCollaboratorsPost(@ModelAttribute Project project, @PathVariable Long projectId, Model model) { 
    Project p = mProjectService.findById(projectId); 


    //mProjectService.save(project); 
    return "redirect:/project_detail/{projectId}"; 
} 

而且模板:

  <form th:action="@{'/project_collaborators/' + ${project.id}}" method="post" th:object="${project}"> 
       <label th:text="'Edit Collaborators: ' + ${project.name}">Edit Collaborators: Website Project</label> 
       <ul class="checkbox-list"> 

        <li th:each="a : ${assignments}"> 
         <span th:text="${a.role.name}" class="primary">Developer</span> 
         <div class="custom-select"> 
          <span class="dropdown-arrow"></span> 
          <select th:field="${a.id}"> 
           <option th:each="collaborator : ${allCollaborators}" th:value="${collaborator.id}" th:text="${collaborator.name}">Michael Pemulis</option> 
          </select> 
         </div> 
        </li> 

       </ul> 
       <div class="actions"> 
        <input type="submit" value="Save" class="button"/> 
        <a href="#" class="button button-secondary">Cancel</a> 
       </div> 
      </form> 

正如你可以看到我想要让用户选择为每个角色(roleNeeded)从任何合作者(allCollaborators)并保留它在List(分配)中分配。

而且我得到错误信息:

ava.lang.IllegalStateException:无论BindingResult也不平原目标 对象bean名称 'A' 可以作为请求属性

所以问题是:如何要解决它,请将模板中的一个数组中的值分配给另一个数组,并在控制器中检索这些值。

回答

1

异常

的原因IllegalStateException异常你得到是因为日:在你的选择元素必须与表单字段=“$ {} a.id”th:object =“$ {project}” element; th:字段属性必须参考项目实例中的实际字段(还需要编写th:field =“* {fieldName}”)。这应该解决你得到的例外,但不会解决你的整个问题,因为它的第二部分涉及到如何使值进入你的控制器,我将在下面解释。

发送的值到控制器

要得到的值到控制器中,你需要做一些修改。由于我并不真正了解你的课程代码,所以我会改变一些东西,以便你能够弄清楚如何使这个简单的例子适应你的特定情况。

首先,我理解你想就像你的形式如下关系:

  • 基于role1 => CollaboratorA
  • role2所=> CollaboratorB

你的控制器需要接收清单并且为了接收这个信息,我们需要两个类别:

  • 将被存储的各个要素数据,映射一个角色ID与合作者id,将类:

    public class RoleCollaborator { 
    
        private Long roleId; 
    
        private Long collaboratorId; 
    
        public Long getRoleId() { 
         return roleId; 
        } 
    
        public void setRoleId(Long roleId) { 
         this.roleId = roleId; 
        } 
    
        public Long getCollaboratorId() { 
         return collaboratorId; 
        } 
    
        public void setCollaboratorId(Long collaboratorId) { 
         this.collaboratorId = collaboratorId; 
        } 
    
    } 
    
  • 一个包装类来存储各个映射的列表:

    public class RolesCollaborators { 
    
        private List<RoleCollaborator> rolesCollaborators; 
    
        public List<RoleCollaborator> getRolesCollaborators() { 
         return rolesCollaborators; 
        } 
    
        public void setRolesCollaborators(List<RoleCollaborator> rolesCollaborators) { 
         this.rolesCollaborators = rolesCollaborators; 
        } 
    
    } 
    

接下来要做的就是改变你的控制器,你有两个方法,一个处理GET请求,另一个处理POST请求,接收你的表单数据。

在得到一个:

public String projectCollaborators(@PathVariable Long projectId, Model model) { 
    (... your code ...) 

    model.addAttribute("project", project); 

    // Add the next line to add the "rolesCollaborators" instance 
    model.addAttribute("rolesCollaborators", new RolesCollaborators()); 

    return "project_collaborators"; 
} 

正如你可以看到,我们增加将由thymeleaf模板中使用的线。现在是一个空白的角色和协作者列表的包装,但如果您需要编辑现有映射而不是添加新映射,则可以添加值。

在后一个:

​​

在这一点上,你的控制器准备接收从表单发送的信息,我们还需要修改。

<form th:action="@{'/project_collaborators/' + ${project.id}}" method="post" th:object="${rolesCollaborators}"> 
    <label th:text="'Edit Collaborators: ' + ${project.name}">Edit Collaborators: Website Project</label> 
    <ul class="checkbox-list"> 

     <li th:each="a, stat : ${assignments}"> 
      <span th:text="${a.role.name}" class="primary">Developer</span> 

      <div class="custom-select"> 
       <input type="hidden" th:id="rolesCollaborators[__${stat.index}__].roleId" th:name="rolesCollaborators[__${stat.index}__].roleId" th:value="${a.role.id}" /> 
       <span class="dropdown-arrow"></span> 
       <select th:field="*{rolesCollaborators[__${stat.index}__].collaboratorId}"> 
        <option th:each="collaborator : ${allCollaborators}" th:value="${collaborator.id}" th:text="${collaborator.name}">Michael Pemulis</option> 
       </select> 
      </div> 
     </li> 

    </ul> 
    <div class="actions"> 
     <input type="submit" value="Save" class="button"/> 
     <a href="#" class="button button-secondary">Cancel</a> 
    </div> 
</form> 

这里有几个变化:

  • 我在指出您需要更改个例外的原因:对象=“$ {项目}”th:object =“$ {rolesCollaborators}”,因为rolesCollaborator是实例名称,您将从其中接收GET控制器方法的值以及将值发送到POST控制器方法的位置。
  • 我添加了一个隐藏的输入;此输入将存储将与用户从界面使用选择元素选取的协作者ID关联发送的角色ID。看看使用的语法。
  • 我改变了日:对象=“$ {} rolesCollaborators”表格属性:您选择元素来指代字段中rollesCollaborators我们次使用对象的字段值。这会将协作者的值设置为RolesCollaborators包装列表的RoleCollaborator元素。

通过这些更改,您的代码将可以正常工作。当然,您可以通过其他一些修改来改进它,但我试图不引入更多修改来专注于您的问题。

+0

非常感谢,完美无缺! – zzheads

+0

@zzheads很高兴听到。请不要忘记接受答案;)。 – BitExodus

+0

当然,做到了。请你能检查我关于同一个项目的另一个问题吗? )在这里:http://stackoverflow.com/questions/38693971/input-type-date-thymeleaf – zzheads