java - Spring 中的 JQuery 数据表与服务器端处理(使用 Java 和 Thymeleaf)

标签 java jquery spring-boot datatables thymeleaf

我有一个使用 Java 和 Thymeleaf 的 Spring Boot 应用程序。其中,我有一个带有 JQuery 数据表的页面。该表中有数千行,因此虽然我目前只是将其全部放在页面上并让 JQuery 完全处理它,但我想切换到使用服务器端处理来进行分页、排序等。

我准备在后端执行此操作,在这里我可以将起始行号和结束行号以及动态排序信息传递给我的 SQL 查询。然而,我的问题是,当用户单击“下一页”按钮或排序按钮时,我无法确切地弄清楚 DataTables 如何尝试通过 Controller 通知我。 我的 Controller 在哪里/如何获取此信息,以便我可以将其插入到我的 SQL 查询中并返回所需的内容?

所以,假设我有一个示例对象,例如“人”。

public class Person {

    private static String PERSON_IMAGE = "<img th:src=\"@{/images/personimage.png}\" alt=\"icon\"/>";
    private static String PERSON_IMAGE_2 = "<img th:src=\"@{/images/personimage2.png}\" alt=\"icon\"/>";

    private String name;
    private String socialSecurity;
    private String birthdate;
    private String gender;
    private String personImage;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSocialSecurity() {
        return socialSecurity;
    }

    public void setSocialSecurity(String socialSecurity) {
        this.socialSecurity = socialSecurity;
    }

    public String getBirthdate() {
        return birthdate;
    }

    public void setBirthdate(String birthdate) {
        this.birthdate = birthdate;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getPersonImage() {
        if(null != birthdate) {
            return PERSON_IMAGE;
        } else {
            return PERSON_IMAGE_2;
        }

    }
}

因此,在我的 Thymeleaf HTML 页面上,我曾经有以下内容:(版本 1)

<table id="myDataTable" class="dataTable display compact">
    <thead>
        <tr>
            <th>Name</th>
            <th>Social Security</th>                                        
            <th>Birthdate</th>
            <th>Gender</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="person : ${peopleList}">
            <td th:attr="data-order=${person.name}"><a th:href="|javascript:openPersonDetail('${person.socialSecurity}');|"><span th:text="${person.name}">name</span></a></td>
            <td th:text="${person.socialSecurity}">socialSecurity</td>                      
            <td class="dt-body-center" th:text="${person.birthdate}">birthdate</td>
            <td class="dt-body-center" th:text="${person.gender}">gender</td>
        </tr>
    </tbody>
</table>

我的页面 Controller 非常简单,只是传入了完整的人员列表,如下:(版本1)

@GetMapping("/ApplicationName/MyDataTablePage")
public String myDataTablePage(Model model) {

    SearchCriteria searchCriteria = new SearchCriteria();
    searchCriteria.setOrderByString("name");
    searchCriteria.setUsePaging(false);
    searchCriteria.setFIRST_NUMBER(null);
    searchCriteria.setLAST_NUMBER(null);

    model.addAttribute("peopleList", myMapperService.getPeople(searchCriteria)); //returns an ArrayList<Person>

    return "/pages/MyDataTablePage";
}

最后,我的 Javascript 曾经有以下内容:(版本 1)

$(document).ready(function() {
    $('#myDataTable').DataTable({
        "destroy" : true,
        "scrollY" : 300,
        "scrollCollapse" : true,
        "paging" : true,
        "autoWidth" : true,
        "ordering" : true,
        "searching" : false,
        "order" : [ [ 0, 'asc' ] ],
        "pageLength" : 20,
        "lengthChange" : false,
        "pagingType" : "full_numbers",
        "dom" : '<"top"ip>rt<"bottom"fl><"clear">'
    });
});

这有效,但我想将数据表切换为使用服务器端处理,因此第一步是(1)更改主页 Controller 以停止将人员列表附加到模型,(2)创建一个新 Controller 将以 JSON 形式返回我的 ArrayList,供 DataTable 自行调用,(3) 更改主页的 html,不再向 DataTable 提供任何 tbody 标记,以及 (4)更改创建表的 JavaScript 以将数据单独放入。

================================================== =============

这让我找到了以下元素的版本 2

我更改的 Thymeleaf HTML 页面:(版本 2)

<table id="myDataTable" class="dataTable display compact">
    <thead>
        <tr>
            <th>Name</th>
            <th>Social Security</th>                                        
            <th>Birthdate</th>
            <th>Gender</th>
        </tr>
    </thead>
</table>

我更改的页面 Controller :(版本2)

@GetMapping("/ApplicationName/MyDataTablePage")
public String myDataTablePage(Model model) {

    return "/pages/MyDataTablePage";
}

我的新 DataTables Controller :

@RequestMapping(path = "/ApplicationName/Data/Person", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public List<Person> getPersonData() {
    System.out.println("I was called!");

    SearchCriteria searchCriteria = new SearchCriteria();
    searchCriteria.setOrderByString("name");
    searchCriteria.setUsePaging(false);
    searchCriteria.setFIRST_NUMBER(null);
    searchCriteria.setLAST_NUMBER(null);

    return myMapperService.getPeople(searchCriteria); //returns an ArrayList<Person>
}

我更改的(更复杂的)Javascript:(版本2)

$(document).ready(function () {
     $('#myDataTable').DataTable({ 
         'destroy' : true,
         'serverSide' : true,
         'sAjaxSource': '/ApplicationName/Data/Person',
         'sAjaxDataProp': '',
         'order': [ [ 0, 'asc' ] ],
         'columns': 
         [ 
            {  'data': 'name',
                'render': function(data, type, row, meta){ 
                    if(type === 'display'){ 
                        data = '<a href="javascript:openPersonDetail(&apos;'+ row.socialSecurity +'&apos;);">' + data + '</a>' 
                    }  
                    return data; 
                } 
            } ,
            { 'data': 'socialSecurity'} ,
            { 'data': 'birthdate'} ,
            { 'data': 'gender'} 
         ],
         'scrollY' : 300,
         'scrollCollapse' : true,
         'paging' : true,
         'autoWidth' : true,
         'ordering' : true,
         'searching' : false,
         'pageLength' : 20,
         'lengthChange' : false,
         'pagingType' : 'full_numbers',
         'dom' : '<"top"ip>rt<"bottom"fl><"clear">' 
     }); 
 });

================================================== =============

这也有效。特别是如果我删除“'serverSide':true”配置 - DataTable 的工作方式与我进行上述更改之前的情况完全相同,但现在它调用我的新数据 JSON Controller ,而不是使用模型属性。

问题:

但是,将“'serverSide':true”配置添加到数据表中后,每次我转到表的新“页面”时,它只会调用我的“/Clinic/Detail/Data/Patient” Controller 每一次。

但是,我需要 DataTables 来传递有关用户选择的页面或用户尝试排序的列的 Controller 信息。我还需要(动态)传递表的总行数(计数),以便 DataTables 可以正确地为用户设置页码。

DataTables 是否会向我的 Controller 发送一些我可以获取的附加参数?像 @PathVariable("whatever") 这样的东西?

我觉得我已经很接近实现这个目标了,但我陷入了困境。

我非常感谢任何帮助!

最佳答案

我找到了两个解决方案:

  1. 看看这篇文章:Spring Boot + Bootstrap + Thymeleaf Datatable
<script>
    $('#example').DataTable({
        "processing": true,
        "serverSide": true,
        "ajax": {
            "url": "/employees",
            "type": "POST",
            "dataType": "json",
            "contentType": "application/json",
            "data": function (d) {
                return JSON.stringify(d);
            }
        },
        "columns": [
            {"data": "name", "width": "20%"},
            {"data": "position","width": "20%"},
            {"data": "office", "width": "20%"},
            {"data": "start_date", "width": "20%"},
            {"data": "salary", "width": "20%"}
        ]
    });
</script>
  • 看看这个 github 项目:spring-data-jpa-datatables
  • 关于java - Spring 中的 JQuery 数据表与服务器端处理(使用 Java 和 Thymeleaf),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55642229/

    相关文章:

    java - 如何使用 ReplaceAll() 方法将整个字符串替换为空值?

    java - 改变骰子的眼睛

    javascript - 在下拉菜单中输入字符时,它会从选项中选择任何随机匹配项并触发更改事件

    java - Spring Security + 根据用户名限制用户

    java - 如何在 jtextpane 中附加 css/html 表

    jquery - 更改主父元素内子 div 的顺序

    javascript - jquery中如何结合打印和删除空输入?

    java - @GetMapping 和 @GetMapping ("/{id}")始终返回 @GetMapping ("/{id}")

    java - Springboot事件发布者有延迟

    spring-boot - 在 Spring Boot 中构建分层 jar 时,如何在层中包含多模块项目 jar?