Skip to content

Latest commit

 

History

History
498 lines (370 loc) · 11.5 KB

model-grid.md

File metadata and controls

498 lines (370 loc) · 11.5 KB

基于数据模型的表格

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

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

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

use App\Models\Movie;
use Encore\Admin\Grid;
use Encore\Admin\Facades\Admin;

$grid = Admin::grid(Movie::class, function(Grid $grid){

    // 第一列显示id字段,并将这一列设置为可排序列
    $grid->id('ID')->sortable();

    // 第二列显示title字段,由于title字段名和Grid对象的title方法冲突,所以用Grid的column()方法代替
    $grid->column('title');
    
    // 第三列显示director字段,通过value($callback)方法设置这一列的显示内容为users表中对应的用户名
    $grid->director()->value(function($userId) {
        return User::find($userId)->name;
    });
    
    // 第四列显示为describe字段
    $grid->describe();
    
    // 第五列显示为rate字段
    $grid->rate();

    // 第六列显示released字段,通过value($callback)方法来格式化显示输出
    $grid->released('上映?')->value(function ($released) {
        return $released ? '' : '';
    });

    // 下面为三个时间字段的列显示
    $grid->release_at();
    $grid->created_at();
    $grid->updated_at();

    // filter($callback)方法用来设置表格的简单搜索框
    $grid->filter(function ($filter) {
    
        // 设置created_at字段的范围查询
        $filter->between('created_at', 'Created Time')->datetime();
    });
});

// 显示表格内容
echo $grid;

Basic Usage

设置表格title

$grid->title('电影列表');

添加列

// 直接通过字段名`username`添加列
$grid->username('用户名');

// 效果和上面一样
$grid->column('username', '用户名');

// 添加多列
$grid->columns('email', 'username' ...);

修改来源数据

$grid->model()->where('id', '>', 100);

$grid->model()->orderBy('id', 'desc');

$grid->model()->take(100);

设置每页显示行数

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

修改显示输出

$grid->text()->display(function($text) {
    return str_limit($text, 30, '...');
});

$grid->name()->display(function ($name) {
    return "<span class='label'>$name</span>";
});

$grid->email()->display(function ($email) {
    return "mailto:$email";
});

// 添加不存在的字段
$grid->column('column_not_in_table')->display(function () {
    return 'blablabla....';
});

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

$grid->first_name();
$grid->last_name();

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

禁用创建按钮

$grid->disableCreation();

禁用分页条

$grid->disablePagination();

禁用页数选择器

$grid->disablePerPageSelector();

禁用查询过滤器

$grid->disableFilter();

禁用导出数据按钮

$grid->disableExport();

禁用批量删除按钮

$grid->disableBatchDeletion();

开启行排序功能

$grid->orderable();

设置分页选择器选项

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

修改行操作按钮

//开启编辑和删除操作
$grid->actions('edit|delete');

//关闭所有操作
$grid->disableActions();

控制列

$grid->rows(function($row){

    //id小于10的行添加style
    if($row->id < 10) {
        $row->style('color:red');
    }

    //指定列只开启编辑操作
    if($row->id % 3) {
        $row->actions('edit');
    }
    
    // 添加自定义操作按钮
    $row->actions()->add(function ($row) {
        return "<a href='/url/{$row->id}'><i class='fa fa-eye'></i></a>";
    });

    //指定列添加自定义操作按钮
    if($row->id % 2) {
        $row->actions()->add(function ($row) {
            return "<a class=\"btn btn-xs btn-danger\">btn</a>";
        });
    }
    
    // 修改column1的显示,使用列column2的值
    $row->column('column1', function ($column1)  use ($row) {
        return $column1 . $row->column2;
    });
});

添加查询过滤器

$grid->filter(function($filter){

    // 如果过滤器太多,可以使用弹出模态框来显示过滤器.
    $filter->useModal();

    // sql: ... WHERE `user.name` LIKE "%$name%";
    $filter->like('name', 'name');

    // sql: ... WHERE `user.email` = $email;
    $filter->is('emial', 'Email');

    // sql: ... WHERE `user.created_at` BETWEEN $start AND $end;
    $filter->between('created_at', 'Created Time')->datetime();
    
    // sql: ... WHERE `article.author_id` = $id;
    $filter->is('author_id', 'Author')->select(User::all()->pluck('name', 'id'));

    // sql: ... WHERE `title` LIKE "%$input" OR `content` LIKE "%$input";
    $filter->where(function ($query) {

        $query->where('title', 'like', "%{$this->input}%")
            ->orWhere('content', 'like', "%{$this->input}%");

    }, 'Text');
    
    // sql: ... WHERE `rate` >= 6 AND `created_at` = {$input};
    $filter->where(function ($query) {

        $query->whereRaw("`rate` >= 6 AND `created_at` = {$this->input}");

    }, 'Text');
    
    // 关系查询,查询对应关系`profile`的字段
    $filter->where(function ($query) {

        $input = $this->input;

        $query->whereHas('profile', function ($query) use ($input) {
            $query->where('address', 'like', "%{$input}%")->orWhere('email', 'like', "%{$input}%");
        });

    }, '地址或手机号');
    
});

关联模型

一对一

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

CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `profiles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`age` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`gender` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

对应的数据模分别为:

class User extends Model
{
    public function profile()
    {
        $this->hasOne(Profile::class);
    }
}

class Profile extends Model
{
    $this->belongsTo(User::class);
}

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

Admin::grid(User::class, function (Grid $grid) {

    $grid->id('ID')->sortable();

    $grid->name();
    $grid->email();
    
    $grid->column('profile.age');
    $grid->column('profile.gender');

    //or
    $grid->profile()->age();
    $grid->profile()->gender();

    $grid->created_at();
    $grid->updated_at();
});

一对多

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

CREATE TABLE `posts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`content` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `comments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`post_id` int(10) unsigned NOT NULL,
`content` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

对应的数据模分别为:

class Post extends Model
{
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

class Comment extends Model
{
    public function post()
    {
        return $this->belongsTo(Post::class);
    }
}

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

return Admin::grid(Post::class, function (Grid $grid) {
    $grid->id('id')->sortable();
    $grid->title();
    $grid->content();

    $grid->comments('评论数')->value(function ($comments) {
        $count = count($comments);
        return "<span class='label label-warning'>{$count}</span>";
    });

    $grid->created_at();
    $grid->updated_at();
});


return Admin::grid(Comment::class, function (Grid $grid) {
    $grid->id('id');
    $grid->post()->title();
    $grid->content();

    $grid->created_at()->sortable();
    $grid->updated_at();
});

多对多

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

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(190) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `users_username_unique` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE TABLE `roles` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `slug` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `roles_name_unique` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

CREATE TABLE `role_users` (
  `role_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  KEY `role_users_role_id_user_id_index` (`role_id`,`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

对应的数据模分别为:

class User extends Model
{
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}

class Role extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class);
    }
}

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

return Admin::grid(User::class, function (Grid $grid) {
    $grid->id('ID')->sortable();
    $grid->username();
    $grid->name();

    $grid->roles()->value(function ($roles) {

        $roles = array_map(function ($role) {
            return "<span class='label label-success'>{$role['name']}</span>";
        }, $roles);

        return join('&nbsp;', $roles);
    });

    $grid->created_at();
    $grid->updated_at();
});