我有一个使用 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(''+ row.socialSecurity +'');">' + 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") 这样的东西?
我觉得我已经很接近实现这个目标了,但我陷入了困境。
我非常感谢任何帮助!
最佳答案
我找到了两个解决方案:
<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/