这是普遍的问题。我有三种模型:项目,角色和协作者(下面列出)。从项目模型中可以看出,它包含需要的角色列表和项目上的协作者列表。创建项目时,它只会添加所需的角色,而将协作者列表保留为空,因此用户可以根据需要的角色随后添加协作者。在尝试向项目中添加新的协作者时,我遇到了一些不确定的解决方法。请参见下面的ProjectController
和project_collaborator
视图,以帮助解决问题。
问题1 :
问题2:
在这一点上,我不确定是否可以解决我的问题,也许我需要对该应用程序进行重新设计。控制器中用于此特定视图的方法为:changeCollaboraters()
和updateCollaborators()
。我还包括了它的外观。如果有人可以帮助,那就太好了。
Project.java
@Entity
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String name;
@NotNull
private String desc;
@NotNull
private String status;
@ManyToMany
@LazyCollection(LazyCollectionOption.FALSE)
private List<Role> rolesNeeded = new ArrayList<>();
@ManyToMany
@LazyCollection(LazyCollectionOption.FALSE)
private List<Collaborator> collaborators = new ArrayList<>();
public Project() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<Role> getRolesNeeded() {
return rolesNeeded;
}
public void setRolesNeeded(List<Role> rolesNeeded) {
this.rolesNeeded = rolesNeeded;
}
public List<Collaborator> getCollaborators() {
return collaborators;
}
}
ProjectController.java
Controller
public class ProjectController {
@Autowired
private ProjectServiceImpl projectService;
@Autowired
private RoleServiceImpl roleService;
@Autowired
private CollaboratorServiceImpl collaboratorService;
@RequestMapping("/projects")
public String getProjects(ModelMap model) {
List<Project> projects = projectService.findAll();
model.put("projects", projects);
return "index";
}
@RequestMapping("/projects/create")
public String addProject(ModelMap model) {
if (!model.containsAttribute("project")) {
model.put("project", new Project());
}
model.put("roles", roleService.findAll());
return "edit_project";
}
@RequestMapping(value = "/projects", method = RequestMethod.POST)
public String addProject(@Valid Project project, BindingResult result, RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
result.getAllErrors().forEach(System.out::println);
return "redirect:/projects/create";
}
projectService.save(project);
return "redirect:/projects";
}
@RequestMapping("/projects/{id}")
@Transactional
public String viewProject(@PathVariable Long id, ModelMap model) {
Project p = projectService.findById(id);
model.put("project", p);
model.put("roleToC", mapRoles(p.getRolesNeeded(), p.getCollaborators()));
return "project_detail";
}
@RequestMapping("/projects/{id}/collaborators")
@Transactional
public String changeCollaborators(@PathVariable Long id, ModelMap model) {
Project p = projectService.findById(id);
model.put("project", p);
model.put("roleToC", mapRoles(p.getRolesNeeded(), p.getCollaborators()));
model.put("collaborators", collaboratorService.findAll());
model.put("action", String.format("/projects/%s", id));
return "project_collaborators";
}
@RequestMapping(value = "/projects/{id}", method = RequestMethod.POST)
public String updateCollaborators(@Valid Project project, BindingResult result, RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
result.getAllErrors().forEach(System.out::println);
return String.format("redirect:/projects/{id}/collaborators");
}
projectService.save(project);
return String.format("redirect:/projects/%s", project.getId());
}
private Map<Role, Collaborator> mapRoles(List<Role> roles, List<Collaborator> collaborators) {
Map<Role, Collaborator> map = new HashMap<>();
for (Role role : roles) {
boolean roleFound = false;
Collaborator collaborator = null;
for (Collaborator c : collaborators) {
if (c.getRole() == role) {
roleFound = true;
collaborator = c;
break;
}
}
if (roleFound) {
map.put(role, collaborator);
} else {
map.put(role, null);
}
roleFound = false;
}
return map;
}
}
project_collaborators.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="base :: head('project_collaborators')"></head>
<body>
<header th:replace="base :: header"></header>
<nav>
<ul>
<li class="selected"><a th:href="@{/projects}">Projects</a></li>
<li><a th:href="@{/collaborators}">Collaborators</a></li>
<li><a th:href="@{/roles}">Roles</a></li>
</ul>
</nav>
<section>
<div class="container wrapper">
<form th:action="@{${action}}" th:method="post" th:object="${project}">
<input type="hidden" th:field="*{desc}">
<input type="hidden" th:field="*{status}">
<input type="hidden" th:field="*{name}">
<label th:text="${'Edit Collaborators: ' + project.name}">Edit Collaborators: Website Project</label>
<ul class="checkbox-list">
<li th:each="element : ${roleToC}"><span class="primary" th:text="${element.key.name}">Developer</span>
<div class="custom-select">
<span class="dropdown-arrow"></span>
<select th:field="*{collaborators}">
<option th:each="c : ${collaborators}" th:if="${#strings.equals(c.role.name, element.key.name)}" th:value="${c.id}" th:text="${c.name}" >Michael Pemulis</option>
</select>
</div>
</li>
</ul>
<div class="actions">
<input type="submit" value="Save" class="button">
<a th:href="@{/projects}" class="button button-secondary">Cancel</a>
</div>
</form>
</div>
</section>
</body>
</html>