问题
I started working on AngularJS and DataTables and wonder whether it is possible to customize the response DataTables
is expecting. The current expectation of the DataTables plugin is something like this:
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 5,
"data": [...]
}
On the server end, the API's are being handled by django-tastypie
The response from server is:
{
meta: {
limit: 20,
next: null,
offset: 0,
previous: null,
total_count: 2
},
objects: [...]
}
So, is there a way to tweak Datatables Plugin to accept/map this response, or I'll have to find a way to add expected fields to the api?
So far I've done this:
var deptTable = angular.element('#deptManagementTable').DataTable({
processing: true,
serverSide: true,
pagingType: "simple_numbers",
ajax: {
url: "/client/api/v1/departments/",
data: function(d) {
d.limit = d.length;
d.offset = d.start;
d.dept_name__icontains = d.search.value;
},
dataSrc: function(json) {
for (var i=0, len=json.objects.length ; i<len ; i++) {
json.objects[i].DT_RowId = json.objects[i].dept_id;
}
return json.objects;
}
},
aLengthMenu: [
[5, 25, 50, 100],
[5, 25, 50, 100]
],
iDisplayLength: 5,
columns: [
{
data: "dept_name"
},
{
data: "dept_created_on",
render: function ( data, type, full, meta ) {
var dateCreated = new Date(data);
dateCreated = dateCreated.toLocaleDateString();
return dateCreated;
}
}
]
});
Any help will be appreciated.
Thanks in Advance :)
回答1:
You can pass a function to the DataTables ajax option, this will give you full control over how to fetch and map the data before passing it to DataTables.
.DataTable({
serverSide: true,
ajax: function(data, callback, settings) {
// make a regular ajax request using data.start and data.length
$.get('/client/api/v1/departments/', {
limit: data.length,
offset: data.start,
dept_name__icontains: data.search.value
}, function(res) {
// map your server's response to the DataTables format and pass it to
// DataTables' callback
callback({
recordsTotal: res.meta.total_count,
recordsFiltered: res.meta.total_count,
data: res.objects
});
});
}
});
The solution above has been tested with jQuery DataTables 1.10.4.
As this question is tagged with Angular, here's a solution for those using angular-datatables.
<div ng-controller="testCtrl">
<table datatable dt-options="dtOptions" dt-columns="dtColumns" class="row-border hover"></table>
</div>
.controller('testCtrl', function($scope, $http, DTOptionsBuilder, DTColumnBuilder) {
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withOption('serverSide', true)
.withOption('ajax', function(data, callback, settings) {
// make an ajax request using data.start and data.length
$http.get('/client/api/v1/departments/', {
limit: data.length,
offset: data.start,
dept_name__icontains: data.search.value
}).success(function(res) {
// map your server's response to the DataTables format and pass it to
// DataTables' callback
callback({
recordsTotal: res.meta.total_count,
recordsFiltered: res.meta.total_count,
data: res.objects
});
});
})
.withDataProp('data'); // IMPORTANT¹
$scope.dtColumns = [
// your column definitions here
];
});
The solution above has been tested with angular-datatables 0.3.0 + DataTables 1.10.4.
¹ The important part to note here is that the angular-datatables solution requires .withDataProp('data')
to work, while the pure jQuery DataTables solution does not have a data: 'data'
option.
回答2:
This answer was very useful, but seems a bit outdated in the context of the current (1.10.12 at the moment) version of datatables, which actually makes life a lot easier (or at least more readable).
Under the current version you can do something like the following in your declaration (bearing in mind that tastypie needs to have the filterable & ordering options set for the fields you want to use).
You can now access the data being submitted in the ajax request by doing data.attr inside the function.
This assumes you wish to restrict searching to one field, but can easily be extended in the same manner do console.log(data) within the ajax function to see what is sent.
var table = $('#tableName').DataTable({
"deferRender":true,
"serverSide": true,
"ajax": function(data, callback, settings) {
var sort_column_name = data.columns[data.order[0].column].data.replace(/\./g,"__");
var direction = "";
if (data.order[0].dir == "desc") { direction = "-"};
$.get('your/tasty/pie/url?format=json', {
limit: data.length,
offset: data.start,
your_search_field__searchattr: data.search.value,
order_by: direction +sort_column_name
}, function(res) {
callback({
recordsTotal: res.meta.total_count,
recordsFiltered: res.meta.total_count,
data: res.objects
});
});
},
"columns": [
{ "data":"column_1", "orderable": false },
{ "data":"column_2" },
{ "data":"column_3" }
],
"order": [[1, "asc"]]
});
来源:https://stackoverflow.com/questions/25211553/datatables-custom-response-handling