基于数据模型的表格

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. useApp\Models\Movie;
  2. useEncore\Admin\Grid;
  3. useEncore\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. returnUser::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. classUserextendsModel
  2. {
  3. publicfunction profile()
  4. {
  5. $this->hasOne(Profile::class);
  6. }
  7. }
  8. classProfileextendsModel
  9. {
  10. publicfunction 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. classPostextendsModel
  2. {
  3. publicfunction comments()
  4. {
  5. return $this->hasMany(Comment::class);
  6. }
  7. }
  8. classCommentextendsModel
  9. {
  10. publicfunction post()
  11. {
  12. return $this->belongsTo(Post::class);
  13. }
  14. }

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

  1. returnAdmin::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. returnAdmin::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. classUserextendsModel
  2. {
  3. publicfunction roles()
  4. {
  5. return $this->belongsToMany(Role::class);
  6. }
  7. }
  8. classRoleextendsModel
  9. {
  10. publicfunction users()
  11. {
  12. return $this->belongsToMany(User::class);
  13. }
  14. }

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

  1. returnAdmin::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. });