表格数据源

数据仓库(Repository)是一个可以提供特定接口对数据进行读写操作的类,通过数据仓库的引入,可以让页面的构建不再关心数据读写功能的具体实现,开发者只需要实现特定的操作接口即可轻松切换数据源。关于数据仓库的详细用法请参考文档数据仓库

{tip} 表格的数据是通过 Dcat\Admin\Contracts\Repository::get 接口获取的。

数据来自模型

{tip} 如果你的数据来自Model,那么你也可以直接使用Model实例,底层会自动把Model转化为数据仓库实例。

当数据源支持Eloquent Model时,只需创建一个简单的Repository类继承Dcat\Admin\Repositories\EloquentRepository即可

  1. <?php
  2. namespace App\Admin\Repositories;
  3. use Dcat\Admin\Repositories\EloquentRepository;
  4. use App\Models\Movie as MovieModel;
  5. class Movie extends EloquentRepository
  6. {
  7. // 这里定义你的模型类名
  8. protected $eloquentClass = MovieModel::class;
  9. // 通过这个方法可以指定查询的字段,默认"*"
  10. public function getGridColumns()
  11. {
  12. return [$this->getKeyName(), 'name', 'title', 'created_at'];
  13. }
  14. }

直接使用模型

如果你还觉得创建 Repository 类麻烦,也可以直接把 Eloquent Model 的实例传递到 Grid 中,底层会自动把 Eloquent Model 转化为 EloquentRepository 实例

  1. use App\Models\Movie as MovieModel;
  2. $grid = new Grid(new MovieModel());
  3. ...

修改来源数据

1、使用 Grid\Model

  1. use App\Admin\Repositories\Movie;
  2. $grid = new Grid(new Movie());
  3. // 添加默认查询条件
  4. $grid->model()->where('id', '>', 100);
  5. // 设置初始排序条件
  6. $grid->model()->orderBy('id', 'desc');
  7. ...

其它查询方法可以参考eloquent的查询方法。

2、使用 Model Query

  1. use App\Models\Movie as MovieModel;
  2. $grid = new Grid(MovieModel::where('id', '>', 100));
  3. ...

关联数据

有以下三种方式让你的表格支持关联数据

1、使用Repository

  1. use App\Admin\Repositories\Movie;
  2. // 相当于 MovieModel::with('categories')
  3. $grid = new Grid(new Movie(['categories']));
  4. $grid->categories;
  5. ...

2、使用 Grid\Model

  1. use App\Admin\Repositories\Movie;
  2. $grid = new Grid(new Movie());
  3. $grid->model()->with('categories');
  4. $grid->categories;
  5. ...

3、使用 Model Query

  1. use App\Models\Movie as MovieModel;
  2. $grid = new Grid(MovieModel::with('categories'));
  3. $grid->categories;
  4. ...

数据来自外部API

示例

如果数据是来自外部的API,只需要覆写Repository中的get方法既可, 具体用法可参考下面的示例,采用豆瓣电影API获取并展示数据:

{tip} 需要注意的是分页和不分页的情况下get方法返回的参数值类型是不同的,具体使用可参考数据仓库 - get

  1. <?php
  2. namespace App\Admin\Repositories;
  3. use Dcat\Admin\Grid;
  4. use Dcat\Admin\Repositories\Repository;
  5. use Illuminate\Pagination\LengthAwarePaginator;
  6. class ComingSoon extends Repository
  7. {
  8. protected $api = 'https://api.douban.com/v2/movie/coming_soon';
  9. /**
  10. * 定义主键字段名称
  11. *
  12. * @return string
  13. */
  14. public function getPrimaryKeyColumn()
  15. {
  16. return '_id';
  17. }
  18. /**
  19. * 查询表格数据
  20. *
  21. * @param Grid\Model $model
  22. * @return LengthAwarePaginator
  23. */
  24. public function get(Grid\Model $model)
  25. {
  26. // 当前页数
  27. $currentPage = $model->getCurrentPage();
  28. // 每页显示行数
  29. $perPage = $model->getPerPage();
  30. // 获取排序字段
  31. [$orderColumn, $orderType] = $model->getSort();
  32. // 获取"scope"筛选值
  33. $city = $model->filter()->input(Grid\Filter\Scope::QUERY_NAME, '广州');
  34. // 如果设置了其他过滤器字段,也可以通过“input”方法获取值,如:
  35. $title = $model->filter()->input('title');
  36. if ($title !== null) {
  37. // 执行你的筛选逻辑
  38. }
  39. $start = ($currentPage - 1) * $perPage;
  40. $client = new \GuzzleHttp\Client();
  41. $response = $client->get("{$this->api}?{$this->apiKey}&city=$city&start=$start&count=$perPage");
  42. $data = json_decode((string)$response->getBody(), true);
  43. return $model->makePaginator(
  44. $data['total'] ?? 0, // 传入总记录数
  45. $data['subjects'] ?? [] // 传入数据二维数组
  46. );
  47. }
  48. }

Grid\Model 常用方法

获取当前页数 (getCurrentPage)

获取当前页码

  • 返回值: int|null 如果不允许分页返回null
    1. $page = $model->getCurrentPage();

获取每页显示行数 (getPerPage)

获取每页显示行数

  • 返回值: int|null 如果不允许分页返回null
    1. $limit = $model->getPerPage();

获取排序字段 (getSort)

获取排序字段

  • 返回值: array [$orderColumn, 'desc'|'asc'] || [null, null]
  1. // $orderColumn 字段名称,如没有进行排序则为 null
  2. // $orderType 正序或倒序: "desc"、"asc",如没有进行排序则为 null
  3. list($orderColumn, $orderType) = $model->getSort();

获取过滤器对象 (filter)

获取过滤器对象,通过过滤器对象可以获取到搜索表单的值,用法如下

  • 返回值 Dcat\Admin\Grid\Filter
  1. // 获取"scope"筛选值
  2. $city = $model->filter()->input(Grid\Filter\Scope::QUERY_NAME, '广州');
  3. // 如果设置了其他过滤器字段,也可以通过“input”方法获取值,如:
  4. $title = $model->filter()->input('title');
  5. if ($title !== null) {
  6. // 执行你的筛选逻辑
  7. }

获取快捷搜索表单值

通过以下方式可以获取到快捷搜索表单值

  1. $quickSearch = $model->grid()->quickSearch()->value();

数据来自复杂SQL查询

如果来源数据需要执行比较复杂的SQL语句获取,那么有两个办法, 第一个办法就是上面的方法,覆盖掉Repositoryget方法实现。

{tip} 需要注意的是分页和不分页的情况下get方法返回的参数值类型是不同的,具体使用可参考数据仓库 - get