简体   繁体   English

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

[英]Spring MVC 4 and Thymeleaf - Prevent page refresh

I promise, I have Googled the heck out of this.我保证,我已经用谷歌搜索过了。

I have a Spring MVC 4 app that uses Thymeleaf to collect form data and put it into a database.我有一个 Spring MVC 4 应用程序,它使用 Thymeleaf 收集表单数据并将其放入数据库。 Works very well, except that I want my application to leave the user on the form page after they hit the submit button, so that they can keep editing.效果很好,除了我希望我的应用程序在用户点击提交按钮后将用户留在表单页面上,以便他们可以继续编辑。

Each time they click submit, the Controller is called and returns the view, which causes the page to refresh.每次他们点击提交时,都会调用控制器并返回视图,这会导致页面刷新。 I would like to eliminate the refresh and also add an alert to confirm the save.我想消除刷新并添加警报以确认保存。

So I started to work on converting the form submission to AJAX and realized that this would defeat the purpose of using Thymeleaf.所以我开始致力于将表单提交转换为 AJAX,并意识到这会违背使用 Thymeleaf 的目的。 Thymeleaf already maps the form fields to the backing bean and does so well, so why replace that mechanism? Thymeleaf 已经将表单字段映射到支持 bean 并且做得很好,那么为什么要替换该机制呢?

So, is there a way to have the Spring MVC controller process the submit request but not return a new instance of the view?那么,有没有办法让 Spring MVC 控制器处理提交请求但不返回视图的新实例?

I tried not returning the view but this caused an error because nothing was mapped to the model attribute.我尝试不返回视图,但这导致了错误,因为没有映射到模型属性。 I tried using @ResponseBody and returning data instead but this caused the JSON to be rendered in the web page, plus I could not figure out how to get that data bask and do something with it.我尝试使用 @ResponseBody 并返回数据,但这导致 JSON 在网页中呈现,而且我无法弄清楚如何获取该数据并对其进行处理。

I also tried to find a way to hook into the submit button to try calling javascript preventDefault() but didn't have any luck there.我还试图找到一种方法来挂钩提交按钮以尝试调用 javascript preventDefault() 但在那里没有任何运气。

Thanks very much for your suggestions...非常感谢您的建议...

Here is my controller code, very straightforward:这是我的控制器代码,非常简单:

@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;
    }

}

So thymeleaf will render the page as a HTML and sends it to client to display, if you want to be able to submit form data to controller without changing pages you need to incorporate Javascript.因此,thymeleaf 会将页面呈现为 HTML 并将其发送到客户端以显示,如果您希望能够将表单数据提交给控制器而不更改页面,则需要合并 Javascript。

You definitely need to use javascript/ajax to post the form contents and keep the page as it is.您肯定需要使用 javascript/ajax 来发布表单内容并保持页面原样。

If you want to update just the section that contains the form for example what you can do is make a call to a controller method that returns a fragment and display the fragment containing the relevant form information.例如,如果您只想更新包含表单的部分,您可以调用一个控制器方法,该方法返回一个片段并显示包含相关表单信息的片段。

Hope this can helps the future readers.希望这可以帮助未来的读者。 We can use th:replace to avoid the javascript/ajax.我们可以使用 th:replace 来避免 javascript/ajax。 See example below.请参阅下面的示例。

@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";
}

Now, in the parent html (like home.html) you use the following.现在,在父 html(如 home.html)中使用以下内容。 *This means replace this tag with the element with id="admin-div" from admin.html *这意味着用 admin.html 中 id="admin-div" 的元素替换这个标签

<div th:replace="~{admin :: #admin-div}">
</div>

Then in a separate html file, place the fragment html code.然后在单独的 html 文件中,放置片段 html 代码。 Wherein in this example its admin.html.其中在这个例子中它的 admin.html。

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

You can put a link/button to trigger to refresh the div element by using a th:href您可以使用 th:href 放置一个链接/按钮来触发刷新 div 元素

<a href="" th:href="@{/admin-reload}"><span>Edit</span></a>

我使用rest控制器和ajax来处理这个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM