首页 > 解决方案 > 为 Crud 类扩展基本数据表类

问题描述

我正在使用 yajra laravel 数据表包。

我试图弄清楚如何将这一点控制器代码重构为一个单独的类(UsersDataTable),我正在使用方法注入使其可访问。这个类扩展了基本的 DataTable 类,但我还没有向这个类添加任何额外的功能。这是我需要帮助理解的。

    public function index(Request $request, UsersDataTable $table, UserFilters $requestFilter)
    {
        $this->authorize('viewList', User::class);

        if ($request->ajax()) {
            $query = User::with('employment');
            $requestFilter->apply($query);

            return $table->eloquent($query)
                ->addColumn('action', 'users.partials.action-cell')
                ->filterColumn('name', function ($query, $keyword) {
                    $sql = "CONCAT(users.first_name, ' ', users.last_name)  like ?";
                    $query->whereRaw($sql, ["%{$keyword}%"]);
                })
                ->filterColumn('id', function ($query, $keyword) {
                    $query->where($query->qualifyColumn('id'), $keyword);
                })
                ->toJson();
        }

        return view('users.index');
    }
<?php

namespace App\DataTables;

use Yajra\DataTables\DataTables;

class UsersDataTable extends DataTables
{

}
<!--begin: Datatable -->
<table id="users_table" data-table="users.index" class="table table-hover"></table>
const table = $('[data-table="users.index"]');
// begin first table
table.DataTable({
    ajax: {
        url: window.location.href,
        data(params) {
            params.status = filterData.status;
            params.started_at = filterData.started_at;
        },
        error: function(xhr, error, code) {
            console.log(JSON.parse(xhr.responseText.errors));
            console.log(xhr);
            console.log(error);
            new Noty({
                type: "error",
                layout: "topRight",
                text: JSON.parse(xhr.responseText.errors)
            }).show();
        }
    },
    columns: [
        { data: "id", title: "User ID" },
        { data: "name", title: "Name" },
        { data: "hometown", title: "Hometown" },
        {
            data: "employment.started_at",
            title: "Date Started",
            searchable: false
        },
        { data: "status", title: "Status", searchable: false },
        {
            data: "action",
            title: "Action",
            orderable: false,
            responsivePriority: -1
        }
    ],
    initComplete(settings) {
        rowCounter.html(`${settings.fnRecordsTotal()} Total`);
    }
});

我的预期结果是我的控制器代码可以重构到 UsersDataTable 类的内部。

更新:

我正在处理下面提供给我的内容,但是,我决定将视图与其 API 分开,以获取用户集合供表使用,因此我不需要使用包创建表。问题是没有运行 dataTable 方法中的代码。我究竟做错了什么?

所以目前作为更新,我有以下内容。

public function index(UsersDataTable $dataTable, UserFilters $requestFilter)
{
    $this->authorize('viewList', User::class);

    $query = User::query();
    $requestFilter->apply($query);

    return $dataTable->eloquent($query)->toJson();
}



<?php

namespace App\DataTables;

use App\Models\User;
use App\Filters\UserFilters;
use Yajra\DataTables\DataTables;

class UsersDataTable extends DataTables
{
    /** @var userFilters */
    private $userFilters;

    /**
     * UserDataTable constructor.
     *
     * @param UserFilters $userFilters
     */
    public function __construct(UserFilters $userFilters)
    {
        $this->userFilters = $userFilters;
    }

    /**
     * Build DataTable class.
     *
     * @param mixed $query Results from query() method.
     * @return \Yajra\DataTables\DataTableAbstract
     */
     public function dataTable($query)
     {
         return datatables($query)
            ->editColumn('started_at', function (User $user) {
                return $user->currentEmployment->started_at->format('Y-m-d H:s');
        })
             ->editColumn('name', function (User $user) {
                return $user->full_name;
            })
            ->filterColumn('id', function ($query, $keyword) {
                $query->where($query->qualifyColumn('id'), $keyword);
            })
            ->filterColumn('name', function ($query, $keyword) {
                $sql = "CONCAT(users.first_name, ' ', users.last_name)  like ?";
                $query->whereRaw($sql, ["%{$keyword}%"]);
            })
            ->addColumn('action', 'users.partials.action-cell');
    }

    /**
     * Get query source of dataTable.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function query($builder)
    {
        $query = User::with('employment');

        $this->userFilters->apply($query);

        return $query;
    }
}

标签: phplaravelyajra-datatable

解决方案


您基本上需要定义UserDataTable如下:

class UsersDataTable extends DataTables
{
    /** @var UserFilters */
    private $userFilters;

    /**
     * UserDataTable constructor.
     *
     * @param UserFilters $userFilters
     */
    public function __construct(UserFilters $userFilters)
    {
        $this->userFilters = $userFilters;
    }

    /**
     * Build DataTable class.
     *
     * @param mixed $query Results from query() method.
     * @return DataTableAbstract
     */
    public function dataTable($query): DataTableAbstract
    {
        return datatables($query)
            ->filterColumn('name', function ($query, $keyword) {
                $sql = "CONCAT(users.first_name, ' ', users.last_name)  like ?";
                $query->whereRaw($sql, ["%{$keyword}%"]);
            })
            ->filterColumn('id', function ($query, $keyword) {
                $query->where($query->qualifyColumn('id'), $keyword);
            })
            ->addColumn('action', 'users.partials.action-cell');
    }

    /**
     * Get query source of dataTable.
     *
     * @return Builder
     */
    public function query(): Builder
    {
        $query = User::with('employment');

        $this->userFilters->apply($query);

        return $query;
    }

    /**
     * Optional method if you want to use html builder.
     *
     * @return HtmlBuilder
     */
    public function html(): HtmlBuilder
    {
        return $this->builder()
            ->columns($this->getColumns())
            ->addAction()
            ->ajax(['type' => 'POST'])
            ->parameters(array_merge(
                $this->getBuilderParameters(),
                [
                    'orderBy' => [[2, 'asc']],
                    'fixedColumns' => [
                        'leftColumns' => 1,
                        'rightColumns' => 1,
                    ],
                ]
            ));
    }

    /**
     * Get columns.
     *
     * @return array
     */
    protected function getColumns(): array
    {
        return [
            ['data' => 'id', 'title' => trans('users.table.header.id')],
            ['data' => 'name', 'title' => trans('users.table.header.name')],
            ['data' => 'email', 'title' => trans('users.table.header.email')],
            ['data' => 'created_at', 'title' => trans('users.table.header.created_at')],
        ];
    }
}

注意:列等可能需要一些调整,这只是一个例子。这个配置基本上替换了你的表格的 JavaScript 配置。

然后,您可以像这样在控制器中使用它:

public function index(UserDataTable $dataTable)
{
    return $dataTable->render('users.index');
}

在您的views/users/index.blade.php中,您只需要渲染表格及其脚本:

<!-- The table -->
{{ $dataTable->table([], true) }}

@push('scripts')
    {!! $dataTable->scripts() !!}
@endpush

推荐阅读