【问题标题】:Using yajra data tables for server side data-tables将 yajra 数据表用于服务器端数据表
【发布时间】:2016-09-17 09:45:58
【问题描述】:

我正在使用 yajra 数据表作为服务器端数据表 我的控制器是这个

public static function alleventsData(Request $request)
{
    $limit = intVal($request->input('length'));
    $start = $request->input('start');
    $meta = EventsRepository::showMeta();
    $totalRecords = $meta[1][1]['Value'];
    $offset = intVal($start);
    $allEvents = EventsRepository::allEvents($offset, $limit);
    return Datatables::collection($allEvents)
    ->addColumn(
        'parent',
        function ($allEvents) {
        return $allEvents['category_name'];
        }
    )
    ->addColumn(
        'venueName',
        function ($allEvents) {
        return $allEvents['venue_name'];
        }
    )
    ->addColumn(
        'venueLocation',
        function ($allEvents) {
        return $allEvents['location'];
        }
    )
    ->addColumn(
        'occurs_at',
        function ($allEvents) {
        return $allEvents['occurs_at'];
        }
    )
    ->addColumn(
        'hot_popular_main',
        function ($allEvents) {
        return '<input type="checkbox" name="hot_popular_main" class= "updatePopertyEvent" attr="hot_popular_main" id="'.$allEvents['id'].'" value="'.$allEvents['hot_popular_main'].'"  '.($allEvents['hot_popular_main']==1?'checked="checked"':'').'/>';
        }
    )
    ->addColumn(
        'synchronize',
        function ($allEvents) {
            return '<button value="'.$allEvents['id'].'" class="btn btn-info synchronize" >Synchronize</button>';
        }
    )
    ->addColumn(
        'status',
        function ($allEvents) {
            $status = $allEvents['status']==1?"Active":"Deactive";
            return '<button value="'.$allEvents['id'].'" class="btn btn-info status" data-attr="'.$allEvents['status'].'">'.$status.'</button>';
        }
    )
    ->with(['recordsTotal'=>$totalRecords, 'recordsFiltered'=>$totalRecords])
    ->make(true);
}

而我的js就是这个

    $(function() {
    $('.eventTableAll').DataTable({
        processing: true,
        serverSide: true,
        ajax: '{!! route('datatables.alleventsData') !!}',
        columns: [
            { data: 'event_name', name: 'event_name' },
            { data: 'parent', name: 'parent', searchable: true },
            { data: 'venueName', name: 'venueName', searchable: true },
            { data: 'venueLocation', name: 'venueLocation', searchable: true },
            { data: 'occurs_at', name: 'occurs_at', searchable: true },
            { data: 'hot_popular_main', name: 'hot_popular_main' },
            { data: 'synchronize', name: 'synchronize' },
            { data: 'status', name: 'status' }

        ]
    });
});

但问题是当我像第二个一样移动到下一页时它没有得到任何数据,我已经看到控制台它正在获取数据但没有嵌入到数据表数据索引中。

【问题讨论】:

    标签: php jquery laravel-5 datatables


    【解决方案1】:

    我在 2 天前遇到了完全相同的问题。 在这里,您手动获取具有限制和偏移的记录,并使用 Datatables::collection()。

    首先,如果您在 laravel 设置中为表单启用了 csrf:

    1. 禁用它。在 Kernel.php 中评论 \App\Http\Middleware\VerifyCsrfToken::class
    2. 或者在datatable js函数之前在ajax header中设置csrf

      $.ajaxSetup({
          headers: { 
             'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          }
      });
      

    如果这样做了。仍然无法正常工作,然后继续进行。


    解决方案 1: 在将获取的数据传递给 Datatables::collection() 之前,请使用:

    $allEvents = collect(array_pad($allEvents->toArray(), -($iDisplayStart + count($allEvents->toArray())), 0));
    

    这一行为您提供响应 Datatables::collection() 的数据,如下所示: 对于第 1 页: 数据 = [ 0=>[event_0], 1=>[event_1], ... 限制=>[event_limit] ];

    对于第 n 页: data = [ 0=>[], 1=>[], ... offset-1=?[], offset=>[event_0], offset+1=>[event_1], ... offset+limit-1 =>[event_limit] ];

    除了在集合中的偏移量之前创建空索引之外别无他法。 这是因为 collection() 或 of() [或任何其他预构建函数] 会考虑 $iDisplayStart 并从 index=$iDisplayStart 开始在集合中查找数据。

    最后

    return Datatable::of($allEvents)
        ->with(['recordsTotal' => $allEventsCount, 'recordsFiltered' => $allEventsCount, 'start' => $iDisplayStart])
        ->make();
    

    解决方案 2: 不用手动实现分页,而是使用 yajra 的预建功能:

    return Datatables::of($allEvents)
        ->filter(function ($allEvents) use ($request, $iDisplayLength, $iDisplayOffset) {
            $allEvents->skip(($iDisplayOffset) * $iDisplayLength)
                ->take($iDisplayLength);
            return $allEvents;
        })
        ->with(['recordsTotal' => $allEventsCount, 'recordsFiltered' => $allEventsCount, 'start' => $iDisplayStart])
        ->make();
    

    参考:https://datatables.yajrabox.com/eloquent/post-column-search


    注意:如果上述解决方案不起作用,请注意所有这些事情:

    • 检查是否包含最新支持的 yajra 数据表 js 库版本
    • 检查您是否从数据库中获取指定限制的数据
    • 检查您正在进行的 ajax 数据表调用是否属于 POST 类型
    • 尝试将这些 ajax 参数切换为 true/false:processing,serverSide。如果在某些旧版本的数据表库中发送 ajax 参数,则这些参数必须设置为 true
    • 在这两种情况下检查返回数据表中是否有这些行 ->with(['recordsTotal' => $allEventsCount, 'recordsFiltered' => $allEventsCount, 'start' => $iDisplayStart])
    • 注意$allEventsCount 是数据库中所有记录的计数。您需要使用-&gt;count() 手动获取它

    解决方案 3:

    如果上述解决方案不起作用, 最后一个解决方案是删除 Yajra 并使用客户端数据表和代码来使用 datatables.js 进行分页。 这不会给你带来性能下降,但你需要做更多的客户端编码。 缓存也可用于客户端数据表。

    参考:https://datatables.net/examples/server_side/pipeline.html
    datatables.net/examples/data_sources/server_side.html

    【讨论】:

    • 解决方案 1 和 3 不起作用,解决方案 2 无法正确搜索
    • 解决方案 1 在我的情况下有效。您能说出您尝试过的解决方案所面临的问题吗?您是否检查了“注意:”部分?
    猜你喜欢
    • 1970-01-01
    • 2020-07-17
    • 2018-06-19
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多