DataTables的使用


分页

使用DataTables插件来实现分页,还带有很多的特殊效果

使用这个需要先引入jQueryjs文件和与之相关的cssjs

分页分为:

  • 客户端分页
    • 优点:简单
    • 缺点:数据多了,服务器加载慢、客户端加载慢、会崩溃
  • 服务端分页

案例

这里拿一个文章列表显示作为案例

方式1

控制器查询文章列表并返回模板页面

public function index()
{
    $data = Article::all();

    return view('admin.article.index', compact('data'));
}

前端显示

<table class="table table-border table-bordered table-hover table-bg table-sort">
    <thead>
        <tr class="text-c">
            <th width="80">ID</th>
            <th width="100">文章标题</th>
            <th width="130">加入时间</th>
            <th width="100">操作</th>
        </tr>
    </thead>
    <tbody>
        @foreach ($data as $item)
        <tr>
            <td>{{ $item->id }}</td>
            <td>{{ $item->title }}</td>
            <td>{{ $item->created_at }}</td>
            <td>
                {{--这里就不写多详细了--}}
                <a>编辑</a>
                <a>删除</a>
            </td>
        </tr>
        @endforeach
    </tbody>
</table>

使用插件进行分页:

$('.table-sort').dataTable();

这样就一个初具规模的看似没毛病的分页就好了,加入有百万级别的数据这里就炸了。

优化

还是使用服务器端进行分页

不过这里使用插件的ajax请求来进行获取数据并进行分页和其他的设置

前端修改

<table class="table table-border table-bordered table-hover table-bg table-sort">
    <thead>
        <tr class="text-c">
            <th width="80">ID</th>
            <th width="100">文章标题</th>
            <th width="130">加入时间</th>
            <th width="100">操作</th>
        </tr>
    </thead>
</table>

这里将循环渲染的部分去掉。减少渲染的时间

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 = `
            <a href="/admin/article/${id}/edit" class="">修改</a>
            <a href="/admin/article/${id}" class="delbtn">删除</a>
        `;
        // 把html添加到td中
        td.html(html);
    }
});

文章作者: Virus
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Virus !
 上一篇
PHP采集知识 PHP采集知识
序言采集文章著名的:火车头、收费、自定义比较差 需要自己编写程序采集目标网站的信息为我所用。 采集必要的知识点: 知道PHP发起网络请求的相关函数: file_get_contents fsockoptn curl 正则表达式/xpa
2020-05-03
下一篇 
RBAC RBAC
简介RBAC:role base access control,基于角色的用户访问权限,就是权限分配给角色,角色又分配给用户 即: 一个用户对应一个角色,一个角色对应多个权限/一个用户对应用户组,一个用户组对应多个权限 数据表设计 注意
2020-04-28
  目录