分页
使用DataTables插件来实现分页,还带有很多的特殊效果
使用这个需要先引入jQuery的js文件和与之相关的css和js
分页分为:
客户端分页
优点:简单
缺点:数据多了,服务器加载慢、客户端加载慢、会崩溃
服务端分页
案例
这里拿一个文章列表显示作为案例
方式1
控制器查询文章列表并返回模板页面
public function index()
{
$data = Article::all();
return view('admin.article.index', compact('data'));
}
前端显示
ID文章标题加入时间操作
@foreach ($data as $item)
{{ $item->id }}{{ $item->title }}{{ $item->created_at }}{{--这里就不写多详细了--}}
编辑
删除
@endforeach
使用插件进行分页:
$('.table-sort').dataTable();
这样就一个初具规模的看似没毛病的分页就好了,加入有百万级别的数据这里就炸了。
优化
还是使用服务器端进行分页
不过这里使用插件的ajax请求来进行获取数据并进行分页和其他的设置
前端修改
ID文章标题加入时间操作
这里将循环渲染的部分去掉。减少渲染的时间
js修改
插件的详细的个别有用的设置都在注释里进行说明
$('.table-sort').dataTable({
// 分页页数选择
lengthMenu: [5, 10, 15, 20, 25, 50, 100],
// 自带的搜索框 隐藏搜索
searching: false,
// 让索引为3的那一列不进行排序,这里为操作那一列
columnDefs: [
{targets: [3], orderable: false}
],
// 开启服务器端分页 开启ajax
serverSide: true,
// 进行ajax请求
ajax: {
// 请求地址
url: "{{ route('admin.article.index') }}",
// 请求方式
type: 'get',
},
// 指定每一列显示的数据
// {data: '表字段名称', defaultContent: '默认内容', className: '样式类'}
columns: [
{data: 'id', className: 'text-c'},
{data: 'title', className: 'text-c'},
{data: 'created_at', className: 'text-c'},
{data: 'action', defaultContent: '操作按钮', className: 'text-c'}
]
});
控制器实现
Laravel没有TP那样有一个request()->isAjax()的判断操作
所以会使用请求头中的ajax信息来判断
这里使用min方法限制请求的个数,防止恶意使用postman进行高额数量的请求造成服务器崩溃
其他的DataTables插件需要返回的格式数据都进行了注释说明
public function index(Request $request)
{
if ($request->header('X-Requested-With') == 'XMLHttpRequest') {
// 开启位置
$start = $request->get('start', 0);
// 获取记录数 min => 防止恶意输入长串数据
$length = min(100, $request->get('length', 10));
// 获取数据
$data = Article::offset($start)->limit($length)->get();
// 记录总数
$total = Article::count();
$result = [
// draw: 客户端调用服务器端次数标识
'draw' => $request->get('draw'),
// recordsTotal: 获取数据记录总条数
'recordsTotal' => $total,
// recordsFiltered: 数据过滤后的总数量
'recordsFiltered' => $total,
// data: 获得的具体数据
'data' => $data,
];
return $result;
}
return view('admin.article.index');
}
在上述中,除了操作部分,基本都能进行显示内容,而编辑,删除这些按钮该如何显示呢?
还记得,RBAC那篇文章中,我们设计了一个Trait来实现权限控制按钮的生成,那是使用访问器来实现的,
这里,我们也使用访问器来实现操作那一列的显示:
{data: 'action', defaultContent: '操作按钮', className: 'text-c'},前端这里的data说明了是数据表字段,但是真正的文章表里甚至别的表里,不存在action这样的字段,所以我们通过模型的追加字段到Attribute中,再配合访问器进行使用。
class Article extends Base
{
// 追加一个字段
protected $appends = ['action'];
/**
* 访问器实现追加字段操作的按钮实现
* @return string
*/
public function getActionAttribute()
{
return $this->editBtn('admin.article.edit').$this->deleteBtn('admin.article.destroy');
}
}
注意!
这里我们基础了Base基础模型,里面已经引入了BtnTrait,所以文章模型里不需要再次引入,而不代表这里没有。
文章列表按钮显示dom方案显示
这里的意思是指{data: 'aaa', defaultContent: '操作按钮', className: 'text-c'},data不再是action的时候,使用回调函数进行渲染,这样也不建议这么玩。
$('.table-sort').dataTable({
// 分页页数选择
lengthMenu: [5, 10, 15, 20, 25, 50, 100],
// 隐藏搜索
searching: false,
columnDefs: [
{targets: [3], orderable: false}
],
// 开启服务器端分页 开启ajax
serverSide: true,
// 进行ajax请求
ajax: {
// 请求地址
url: "{{ route('admin.article.index') }}",
// 请求方式
type: 'get',
},
// 指定每一列显示的数据
columns: [
{data: 'id', className: 'text-c'},
{data: 'title', className: 'text-c'},
{data: 'created_at', className: 'text-c'},
{data: 'aaa', defaultContent: '操作按钮', className: 'text-c'}
],
// 回调方法
// row 当前行的dom对象
// data: 当前行的数据
// dataIndex: 当前行的数据索引
createdRow: function (row, data, dataIndex) {
// 行的最后一列
// console.log($(row).find('td:last-child'));
var td = $(row).find('td:last-child');
// 当前id号
var id = data.id;
// 显示的html内容
var html = `
`;
// 把html添加到td中
td.html(html);
}
});