基于数据模型的表格

Encore\Admin\Grid类用于生成基于数据模型的表格,先来个例子,数据库中有movies

  1. CREATE TABLE `movies` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  4. `director` int(10) unsigned NOT NULL,
  5. `describe` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  6. `rate` tinyint unsigned NOT NULL,
  7. `released` enum(0, 1),
  8. `release_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  9. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  10. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

对应的数据模型为App\Models\Movie,下面的代码可以生成表movies的数据表格:

  1. use App\Models\Movie;
  2. use Encore\Admin\Grid;
  3. use Encore\Admin\Facades\Admin;
  4. $grid = Admin::grid(Movie::class, function(Grid $grid){
  5. // 第一列显示id字段,并将这一列设置为可排序列
  6. $grid->id('ID')->sortable();
  7. // 第二列显示title字段,由于title字段名和Grid对象的title方法冲突,所以用Grid的column()方法代替
  8. $grid->column('title');
  9. // 第三列显示director字段,通过display($callback)方法设置这一列的显示内容为users表中对应的用户名
  10. $grid->director()->display(function($userId) {
  11. return User::find($userId)->name;
  12. });
  13. // 第四列显示为describe字段
  14. $grid->describe();
  15. // 第五列显示为rate字段
  16. $grid->rate();
  17. // 第六列显示released字段,通过display($callback)方法来格式化显示输出
  18. $grid->released('上映?')->display(function ($released) {
  19. return $released ? '是' : '否';
  20. });
  21. // 下面为三个时间字段的列显示
  22. $grid->release_at();
  23. $grid->created_at();
  24. $grid->updated_at();
  25. // filter($callback)方法用来设置表格的简单搜索框
  26. $grid->filter(function ($filter) {
  27. // 设置created_at字段的范围查询
  28. $filter->between('created_at', 'Created Time')->datetime();
  29. });
  30. });

基本使用方法

添加列

  1. // 直接通过字段名`username`添加列
  2. $grid->username('用户名');
  3. // 效果和上面一样
  4. $grid->column('username', '用户名');
  5. // 添加多列
  6. $grid->columns('email', 'username' ...);

修改来源数据

  1. $grid->model()->where('id', '>', 100);
  2. $grid->model()->orderBy('id', 'desc');
  3. $grid->model()->take(100);

设置每页显示行数

  1. // 默认为每页20条
  2. $grid->paginate(15);

修改显示输出

  1. $grid->text()->display(function($text) {
  2. return str_limit($text, 30, '...');
  3. });
  4. $grid->name()->display(function ($name) {
  5. return "<span class='label'>$name</span>";
  6. });
  7. $grid->email()->display(function ($email) {
  8. return "mailto:$email";
  9. });
  10. // 添加不存在的字段
  11. $grid->column('column_not_in_table')->display(function () {
  12. return 'blablabla....';
  13. });

display()方法接收的匿名函数绑定了当前行的数据对象,可以在里面调用当前行的其它字段数据

  1. $grid->first_name();
  2. $grid->last_name();
  3. // 不存的字段列
  4. $grid->column('full_name')->display(function () {
  5. return $this->first_name.' '.$this->last_name;
  6. });

禁用创建按钮

  1. $grid->disableCreateButton();

禁用分页条

  1. $grid->disablePagination();

禁用查询过滤器

  1. $grid->disableFilter();

禁用导出数据按钮

  1. $grid->disableExport();

禁用行选择checkbox

  1. $grid->disableRowSelector();

禁用行操作列

  1. $grid->disableActions();

设置分页选择器选项

  1. $grid->perPages([10, 20, 30, 40, 50]);

添加查询过滤器

  1. $grid->filter(function($filter){
  2. // 如果过滤器太多,可以使用弹出模态框来显示过滤器.
  3. $filter->useModal();
  4. // 禁用id查询框
  5. $filter->disableIdFilter();
  6. // sql: ... WHERE `user.name` LIKE "%$name%";
  7. $filter->like('name', 'name');
  8. // sql: ... WHERE `user.email` = $email;
  9. $filter->is('emial', 'Email');
  10. // sql: ... WHERE `user.created_at` BETWEEN $start AND $end;
  11. $filter->between('created_at', 'Created Time')->datetime();
  12. // sql: ... WHERE `author_id` = $id;
  13. $filter->is('author_id', 'Author')->select(User::all()->pluck('name', 'id'));
  14. // sql: ... WHERE `title` LIKE "%$input" OR `content` LIKE "%$input";
  15. $filter->where(function ($query) {
  16. $query->where('title', 'like', "%{$this->input}%")
  17. ->orWhere('content', 'like', "%{$this->input}%");
  18. }, 'Text');
  19. // sql: ... WHERE `rate` >= 6 AND `created_at` = {$input};
  20. $filter->where(function ($query) {
  21. $query->whereRaw("`rate` >= 6 AND `created_at` = {$this->input}");
  22. }, 'Text');
  23. // 关系查询,查询对应关系`profile`的字段
  24. $filter->where(function ($query) {
  25. $input = $this->input;
  26. $query->whereHas('profile', function ($query) use ($input) {
  27. $query->where('address', 'like', "%{$input}%")->orWhere('email', 'like', "%{$input}%");
  28. });
  29. }, '地址或手机号');
  30. });

关联模型

一对一

users表和profiles表通过profiles.user_id字段生成一对一关联

  1. CREATE TABLE `users` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  4. `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  5. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  6. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  9. CREATE TABLE `profiles` (
  10. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  11. `user_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  12. `age` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  13. `gender` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  14. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  15. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  16. PRIMARY KEY (`id`)
  17. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

对应的数据模分别为:

  1. class User extends Model
  2. {
  3. public function profile()
  4. {
  5. $this->hasOne(Profile::class);
  6. }
  7. }
  8. class Profile extends Model
  9. {
  10. public function user()
  11. {
  12. $this->belongsTo(User::class);
  13. }
  14. }

通过下面的代码可以关联在一个grid里面:

  1. Admin::grid(User::class, function (Grid $grid) {
  2. $grid->id('ID')->sortable();
  3. $grid->name();
  4. $grid->email();
  5. $grid->column('profile.age');
  6. $grid->column('profile.gender');
  7. //or
  8. $grid->profile()->age();
  9. $grid->profile()->gender();
  10. $grid->created_at();
  11. $grid->updated_at();
  12. });

一对多

posts表和comments表通过comments.post_id字段生成一对多关联

  1. CREATE TABLE `posts` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  4. `content` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  5. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  6. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  9. CREATE TABLE `comments` (
  10. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  11. `post_id` int(10) unsigned NOT NULL,
  12. `content` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  13. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  14. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  15. PRIMARY KEY (`id`)
  16. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

对应的数据模分别为:

  1. class Post extends Model
  2. {
  3. public function comments()
  4. {
  5. return $this->hasMany(Comment::class);
  6. }
  7. }
  8. class Comment extends Model
  9. {
  10. public function post()
  11. {
  12. return $this->belongsTo(Post::class);
  13. }
  14. }

通过下面的代码可以让两个模型在grid里面互相关联:

  1. return Admin::grid(Post::class, function (Grid $grid) {
  2. $grid->id('id')->sortable();
  3. $grid->title();
  4. $grid->content();
  5. $grid->comments('评论数')->display(function ($comments) {
  6. $count = count($comments);
  7. return "<span class='label label-warning'>{$count}</span>";
  8. });
  9. $grid->created_at();
  10. $grid->updated_at();
  11. });
  12. return Admin::grid(Comment::class, function (Grid $grid) {
  13. $grid->id('id');
  14. $grid->post()->title();
  15. $grid->content();
  16. $grid->created_at()->sortable();
  17. $grid->updated_at();
  18. });

多对多

usersroles表通过中间表role_users产生多对多关系

  1. CREATE TABLE `users` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `username` varchar(190) COLLATE utf8_unicode_ci NOT NULL,
  4. `password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
  5. `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  6. `created_at` timestamp NULL DEFAULT NULL,
  7. `updated_at` timestamp NULL DEFAULT NULL,
  8. PRIMARY KEY (`id`),
  9. UNIQUE KEY `users_username_unique` (`username`)
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
  11. CREATE TABLE `roles` (
  12. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  13. `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  14. `slug` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  15. `created_at` timestamp NULL DEFAULT NULL,
  16. `updated_at` timestamp NULL DEFAULT NULL,
  17. PRIMARY KEY (`id`),
  18. UNIQUE KEY `roles_name_unique` (`name`)
  19. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
  20. CREATE TABLE `role_users` (
  21. `role_id` int(11) NOT NULL,
  22. `user_id` int(11) NOT NULL,
  23. `created_at` timestamp NULL DEFAULT NULL,
  24. `updated_at` timestamp NULL DEFAULT NULL,
  25. KEY `role_users_role_id_user_id_index` (`role_id`,`user_id`)
  26. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

对应的数据模分别为:

  1. class User extends Model
  2. {
  3. public function roles()
  4. {
  5. return $this->belongsToMany(Role::class);
  6. }
  7. }
  8. class Role extends Model
  9. {
  10. public function users()
  11. {
  12. return $this->belongsToMany(User::class);
  13. }
  14. }

通过下面的代码可以让两个模型在grid里面互相关联:

  1. return Admin::grid(User::class, function (Grid $grid) {
  2. $grid->id('ID')->sortable();
  3. $grid->username();
  4. $grid->name();
  5. $grid->roles()->display(function ($roles) {
  6. $roles = array_map(function ($role) {
  7. return "<span class='label label-success'>{$role['name']}</span>";
  8. }, $roles);
  9. return join('&nbsp;', $roles);
  10. });
  11. $grid->created_at();
  12. $grid->updated_at();
  13. });