Spring MVC 4和Thymeleaf - 防止页面刷新

3

我保证,我已经在Google上搜索了很多次。

我有一个使用Thymeleaf收集表单数据并将其存入数据库的Spring MVC 4应用程序。它运行得非常好,但我希望我的应用程序在用户点击提交按钮后留在表单页面,以便他们可以继续编辑。

每次他们点击提交按钮时,控制器被调用并返回视图,这会导致页面刷新。我想消除刷新,并添加一个确认保存的提示框。

因此,我开始着手将表单提交转换为AJAX,但意识到这将破坏使用Thymeleaf的目的。Thymeleaf已经将表单字段映射到后台bean中,并且执行得很好,那么为什么要替换该机制呢?

那么,有没有一种方法可以使Spring MVC控制器处理提交请求,但不返回新的视图实例?

我尝试不返回视图,但这会导致错误,因为没有任何内容映射到模型属性。我尝试使用@ResponseBody并返回数据,但这会导致JSON呈现在网页中,而且我无法弄清楚如何将数据返回并对其进行操作。

我还尝试找到一种方法来挂钩提交按钮,尝试调用javascript preventDefault(),但没有任何幸运。

非常感谢您的建议...

这是我的控制器代码,非常简单:

@SessionAttributes("adminFormAjax")
@Controller
public class TestController 
{
    @Autowired
    private AdminDataRepository rep;

    @RequestMapping(value="/admin_ajax", method=RequestMethod.GET)
    public String adminFormAjax(Model model) 
    {
        AdminData ad = rep.findById(1L);

        // If there is no configuration record, create one and assign the primary key as 1.
        if(ad == null)
        {
            ad = new AdminData();
            ad.setId(1L);
        }

        model.addAttribute("adminFormAjax", ad);
        return "adminFormAjax";
    }

    @RequestMapping(value="/admin_ajax", method=RequestMethod.POST)
    public @ResponseBody AdminData adminSubmit(@ModelAttribute("adminFormAjax") AdminData ad, Model model) 
    {
        // rep.save(ad);
        model.addAttribute("adminFormAjax", ad);
        return ad;
    }

}
3个回答

4

Thymeleaf会将页面渲染为HTML并发送给客户端进行显示,如果您想在不更改页面的情况下能够提交表单数据到控制器,则需要集成JavaScript。

您绝对需要使用JavaScript / Ajax来发布表单内容并保持页面不变。

例如,如果您想仅更新包含表单的部分,您可以调用一个返回片段的控制器方法,并显示包含相关表单信息的片段。


好的,谢谢。我尝试了这个方法,但是当我点击提交按钮时似乎无法调用JavaScript。Thymeleaf是否会拦截提交按钮调用的函数? - Jim Archer
不,记住 Thymeleaf 是服务器端渲染。如果 JavaScript 不起作用,那么问题就在于 JavaScript 代码本身。如果您想提出一个新的问题来展示您遇到的问题(包括代码展示),我可以帮忙查看一下。 - Aeseir
感谢Aeseir,后续在https://dev59.com/Co3da4cB1Zd3GeqPyVV7中。 - Jim Archer

3
希望这能帮助未来的读者。我们可以使用th:replace来避免使用javascript/ajax。请参见以下示例。
@GetMapping("/admin-reload")
public String reloadElementDiv(Model model) {       
    AdminData ad = rep.findById(1L);

    // If there is no configuration record, create one and assign the primary key as 1.
    if(ad == null)
    {
        ad = new AdminData();
        ad.setId(1L);
    }

    model.addAttribute("adminAttrib", ad);

    return "adminForm";
}

现在,在父HTML文件(如home.html)中,您可以使用以下代码。 *这意味着将此标签替换为来自admin.html的id="admin-div"元素。
<div th:replace="~{admin :: #admin-div}">
</div>

然后在另一个HTML文件中,放置片段HTML代码。在这个例子中,它是admin.html。

<div id="admin-div">
   <span th:text="${ad.id}"></span>
</div>

您可以使用th:href将链接/按钮放置在页面上,以触发刷新div元素。
<a href="" th:href="@{/admin-reload}"><span>Edit</span></a>

0

我正在使用Rest Controller和Ajax来处理这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接