我有一个视图,其中有一个用于创建新的Exercise对象的窗体和一个用于显示所有练习的表格。现在,我希望该表随新创建的练习自动刷新。当前它将表显示为空,直到我再次手动转到localhost:8080/exercise
。
这是我的控制器:
@Controller
public class ExerciseController {
@Autowired
private ExerciseService exerciseService;
@Autowired
private ModelMapper modelMapper;
@GetMapping("/exercise")
public String exerciseView(final Model model) {
List<Exercise> exerciseList = exerciseService.getAllExercises();
model.addAttribute("exerciseDTO", new ExerciseDTO());
model.addAttribute("title", "Create an Exercise");
model.addAttribute("exercises", exerciseList);
return "exercise";
}
@PostMapping("/exercise")
public String createExercise(@ModelAttribute final ExerciseDTO exerciseDto) {
final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);
this.exerciseService.createExercise(exercise);
return "exercise";
}
}
还有我的百里香模板:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
<header th:replace="template :: navbar"></header>
<h1>Form</h1>
<form action="#" th:action="@{/exercise}" th:object="${exerciseDTO}" method="post">
<p>Name: <input type="text" th:field="*{name}" /></p>
<p>Description: <input type="text" th:field="*{description}" /></p>
<p>Exercise type:
<select th:field="*{type}" id="typeSelector">
<option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
th:value="${type}" th:text="${type.displayName}">
</option>
</select>
</p>
<p id="bpmRow">BPM: <input type="number" th:field="*{bpm}" id="bpmInput" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<br>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>BPM</th>
</tr>
<tr th:each="exercise : ${exercises}">
<td th:text="${exercise.name}"></td>
<td th:text="${exercise.description}"></td>
<td th:text="${exercise.type}"></td>
<td th:text="${exercise.bpm}"></td>
</tr>
</table>
</body>
</html>
现在,我认为返回“运动”的createExercise
方法将调用exerciseView
方法,从而调用exerciseService.getAllExercises()
。有没有办法实现此功能?还是有一种更好的方法,而无需重新加载整个页面?
答案 0 :(得分:1)
要在不刷新页面的情况下提供数据,您需要诸如Angular或React之类的客户端技术。或普通的旧javascript。但是您无法在无页面刷新的Spring MVC中向页面提供新数据。
答案 1 :(得分:1)
您可以使用AJAX将请求从客户端发送到服务器端并接收答案,而无需刷新页面。
不幸的是,我没有足够的时间,并且我无法完成代码,但是您可以执行以下操作:
function submitItems() {
var contextPath = $("meta[name='ctx']").attr("content");
var exerciseDto = {};
exerciseDto.name = $("#name").val();
exerciseDto.description = $("#description").val();
exerciseDto.typeSelector = $("#typeSelector).val();
exerciseDto.bpmInput = $("#bpmInput").val();
$.ajax({
dataType : "json",
type : "post",
url : contextPath + "/exercise",
data : JSON.stringify(exerciseDto),
cache : false,
contentType : "application/json",
beforeSend : function(xhr) {
xhr.setRequestHeader(header, token);
},
success : function(data) {
console.log(data);
//HERE YOU NEED ACTION TO UPDATE TABLE.
},
error : function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR.responseText);
console.log('getJSON request failed! ' + textStatus);
}
});
}
然后您的视图必须是这样的:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
<header th:replace="template :: navbar"></header>
<h1>Form</h1>
<form onsubmit="submitItems();return false;">
<p>Name: <input id="name" type="text" /></p>
<p>Description: <input id="description" type="text" /></p>
<p>Exercise type:
<select th:field="*{type}" id="typeSelector">
<option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
th:value="${type}" th:text="${type.displayName}">
</option>
</select>
</p>
<p id="bpmRow">BPM: <input type="number" id="bpmInput" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<br>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>BPM</th>
</tr>
<tr th:each="exercise : ${exercises}">
<td th:text="${exercise.name}"></td>
<td th:text="${exercise.description}"></td>
<td th:text="${exercise.type}"></td>
<td th:text="${exercise.bpm}"></td>
</tr>
</table>
</body>
</html>
请记住,您需要创建一个将更新表的JS操作。有很多方法可以做到这一点(您可以将新数据推送到数据表或使用JS函数添加新内容)。
我希望这可以帮助您更多地了解AJAX的工作原理。
PS。您还必须更新控制器以返回结果,在您的实例中将是
@PostMapping("/exercise")
public createExerciseDomainTYPEHERE createExercise(@RequestBody final ExerciseDTO exerciseDto) {
final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);
//this.exerciseService.createExercise(exercise);
//return "exercise";
return this.exerciseService.createExercise(exercise);
}
您将不得不更改此行
public createExerciseDomainTYPEHERE createExercise(@RequestBody final ExerciseDTOexerciseDto){
到您的createExercise域类型。