【问题标题】:Thymeleaf: Update Table on Form SubmitThymeleaf:表单提交更新表
【发布时间】:2019-10-09 05:47:32
【问题描述】:

我有一个视图,其中有一个用于创建新练习对象的表单和一个用于显示所有练习的表格。现在我希望表格自动刷新新创建的练习。目前它将表格显示为空,直到我再次手动转到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()。有没有办法实现这个功能?或者有没有更好的方法,无需重新加载整个页面?

【问题讨论】:

    标签: java spring thymeleaf


    【解决方案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 操作。有很多方法可以做到这一点(您可以将新数据推送到 Datatable 或使用 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 finalExerciseDTO exerciseDto) {

    到您的 createExercise 域类型。

    【讨论】:

    • 我不认为 $(..)$. 语法是 JavaScript 的一部分。我将如何使用纯 JavaScript 来做到这一点?
    【解决方案2】:

    要在不刷新页面的情况下提供数据,您需要 Angular 或 React 等客户端技术。或普通的旧javascript。但是你不能在没有页面刷新的 spring mvc 中为页面提供新数据。

    【讨论】:

    • 感谢您的回答。我宁愿不使用 JS 框架,因为我只是想学习纯 JavaScript。你能否给我一个关于如何解决类似问题的提示?
    • @marc,我怎样才能让它与页面刷新一起工作。我正在将百里香与弹簧 MVC 一起使用。目前正在尝试弄清楚如何实现搜索功能以显示搜索结果
    • 最简单的方法是使用 sql LIKE 运算符来获取结果。
    猜你喜欢
    • 1970-01-01
    • 2018-07-23
    • 2021-01-28
    • 2023-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 2013-03-09
    相关资源
    最近更新 更多