在不重新加载整个页面的情况下更新 Thymeleaf 中的内容

Update content in Thymeleaf without reloading whole page

我想在不重新加载整个页面的情况下更新 div“输出”的内容。当用户输入内容并点击 运行 按钮时,服务器将在 div“输出”上输出评估。但是下面的代码只在浏览器上显示 div “输出”。另一页不见了。我做错了什么?

<body>
    <div class="container mx-auto">
        <div th:insert="fragments/body :: navigation (true, ${spieler.name}, ${spieler.punkte}, ${spieler.level})"></div>
    
        <div class="d-flex justify-content-center">
            <label class="text-center mt-4" id="thetext">Du liebst Abenteuer und möchte endlich reisen.<br>
                Du hast ein bisschen Geld und das reicht für ein Ticket zur nächsten Insel.<br>
                Unglücklicherweise ist dein Schiff in einem Sturm gesunken. <br>
                Du hat glück, an einen Strand zu landen. <br><br>
                Jetzt musst du die Herausforderungen mit deinen SQL-Kenntnissen meistern.<br>
                Je schneller du die Probleme löst, desto besser ist dein Ranking.<br><br>
                Viel Spaß !!!<br>
            </label>
        </div>
    
        <div class="d-flex justify-content-center">
            <input id="startButton" onclick="nachsteFrage()" class="btn-secondary mt-4"
                   type="button" value="Weiter">
        </div>
    
        <form method="post"  th:action="@{/level1-answer}" th:object="${answer}">
            <div class="form-group">
                <input type="text" class="form-control mt-4" id="codeArea" name="antwort" th:field = "*{SQL}"
                          rows="3" placeholder="Hier steht dein Code ...">
                <br>
                <div class="d-flex justify-content-center">
                    <button onclick="updateOutput()" class="btn-secondary mt-4"
                             id="ausfuehrenBtn">run</button>
                </div>
            </div>
        </form>
        <div id="output" style="overflow:scroll; height:400px;">
             <span th:text = "${evaluation}"></>
        </div>
    
    </div>
    
    <script th:inline="javascript">
        function updateOutput() {
            $.get("output").done(function(fragment) { 
                $("#output").replaceWith(fragment);
            });
        }
    </script>
</body>

控制器

@RequestMapping(value="/level1-answer", method=RequestMethod.POST)
public String postSQL (Model map, @ModelAttribute("answer") Answer answer) {
    map.addAttribute("evaluation",answer.getSQL() + "  this is correct or incorrect"); 
    return "level1 :: #output";
}

html 文件位于 templates/level1.html

这是一个非常基本的演示,展示了一种方法。

我从主页开始 testajax.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title>Test Ajax Fragment</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    </head>
    <body>
        <h3>A Permanent Heading</h3>
        <div id="output">
            Some initial text displayed here. This will be replaced.
        </div>
        <br>
        <button onclick="updateOutput()" 
                id="ausfuehrenBtn">run</button>
        <script>
            function updateOutput() {
                $.post("test_ajax_frag").done(function (fragment) {
                    console.log(fragment);
                    $("#output").replaceWith(fragment);
                });
            }
        </script>
    </body>
</html>

请注意这里没有 <form>,因为我们不会提交任何表单数据 - 我们稍后将使用 Ajax 请求。

用于显示此页面的控制器:

@RequestMapping(value="/test_ajax", method=RequestMethod.GET)
public String sendHtml(Model map) {
    //map.addAttribute("foo", "bar");
    return "testajax";
}

这是一个简单的 GET 处理程序,用于显示初始页面。在这种情况下,我什至没有任何具体的 Model 数据,只是为了简化演示。

Thymeleaf 片段模板是 testajaxfragment.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <body>
        <div th:fragment="test_frag">
            <div id="output">
                Some replacement content.
            </div>
        </div>
    </body>
</html>

主页包含一个 Ajax 调用,在单击按钮时执行:

$.post("test_ajax_frag")

为此我们需要一个单独的控制器:

@RequestMapping(value="/test_ajax_frag", method=RequestMethod.POST)
public String sendHtmlFragment(Model map) {
    //map.addAttribute("foo", "bar");
    return "testajaxfragment :: test_frag";
}

在这种情况下,我选择在 Ajax 调用中使用 POST 请求 - 因此控制器也必须是 POST 处理程序。

当控制器运行时,它 returns 调用它的 JavaScript 函数的 HTML 片段。然后该函数替换 output div:

$("#output").replaceWith(fragment);

这是一种相当粗糙的方法,但显示了您在问题和评论中询问的技术。