У меня есть приложение Spring Boot, использующее Java и Thymeleaf. В нем у меня есть страница с JQuery DataTable. В этой таблице тысячи строк, и поэтому в настоящее время я просто помещаю все это на страницу и позволяю JQuery полностью ее обрабатывать, но я хочу переключиться на использование обработки ServerSide для разбивки на страницы, сортировки и т. Д.
Я настроен на выполнение этого на бэк-энде, где я могу передать начальный и конечный номер строки и динамически сортировать информацию в свой SQL-запрос. Однако моя проблема в том, что я просто не могу понять, как именно DataTables пытается уведомить меня через контроллер, когда пользователь нажимает кнопку «Следующая страница» или кнопку сортировки. Где / как мой контроллер может получить эту информацию, чтобы я мог вставить ее в свой 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>
Моя страница контроллер был очень прост и просто передан в полном списке людей следующим образом: (Версия 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">'
});
});
Это сработало, но я хотел переключить DataTable для использования серверной обработки, и поэтому первым шагом было (1) изменить контроллер главной страницы, чтобы прекратить добавлять список людей в модель, (2) создать новый контроллер, который будет возвращать мой ArrayList в виде JSON, чтобы DataTable вызывал сам по себе, (3) изменить HTML-код главной страницы, чтобы больше не предоставлять тег tbody для DataTable, и (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>
Моя измененная страница контроллер : (версия 2)
@GetMapping("/ApplicationName/MyDataTablePage")
public String myDataTablePage(Model model) {
return "/pages/MyDataTablePage";
}
Мои новые DataTables контроллер :
@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 работает точно так же, как раньше, до того как я сделал вышеупомянутые изменения, но теперь он вызывает мой новый контроллер Data JSON вместо использования атрибута модели.
Проблема:
Однако, с конфигурацией «serverSide»: true, добавленной в DataTable, каждый раз, когда я захожу на новую «страницу» таблицы, она просто вызывает мой контроллер «/ Clinic / Detail / Data / Patient» каждый раз.
Но мне нужны DataTables, чтобы передать моему контроллеру информацию о том, какую страницу выбрал пользователь или по какому столбцу пользователь пытался отсортировать. Мне также нужно передать в таблицу (динамически) общее количество строк (количество), чтобы DataTables могли правильно настроить номера страниц для пользователя.
Отправляет ли DataTables некоторые дополнительные параметры моему контроллеру, которые я могу подобрать? Что-то вроде @PathVariable («что угодно»)?
Я чувствую, что я так близок к тому, чтобы заставить это работать, но я застрял в этой точке.
Буду очень признателен за любую помощь!