扩展 Laravel-admin,实现一行代码展现内联表格的功能,自动加页码,换页无刷新并保持展开状态(column-relation v3 预览 - 内联更新兼容 IE10+)
column-relation v2.0 实现换页无刷新效果(4楼)
v2.2 新增条件查询及排序(12楼)
v3 预览 - 内联表格的更新操作兼容IE10(18楼)
以下 2020.2.16 内容
目前laravel-admin v1.7.9的行展开函数expand(..)是没有页码的,想要添加页码则必须自己实现。如2.9日所述,使用回调函数的写法的确可以添加页码,可惜这个函数写起来还是挺烦的,代码很多行。而模型关联的情况非常普遍,针对每一个关联属性都要定制一个回调函数,这必定是件很烦人的事情。
用法
为解决上述问题,我写了一个函数relate()
,仅需一行代码即可展现内联表格,用起来非常方便!看起来就像下面这样
$grid = new Grid(new Category());
$grid->column('name', '类别')
->relate('topics', ['id', 'title'=>'话题']);
这是分类控制器里的代码,内容分类与话题之间是使用函数topics()建立起一对多的关联关系的。因此,在relate()函数中,第一个参数就要写成topics。第二个参数是个数组,对应内联表格里面需要显示的字段。
上述relate()函数仅需两个参数就可以华丽的呈现内联表格(有页码、换页保持展开状态)。如果想要进一步格式化内联表格,可以象下面这样传递一个回调函数作为第三个参数(第四个参数更改每页显示个数,默认4个)。
$grid = new Grid(new Role());
$grid->column('name', '角色名称')
->relate('users', ['id', 'name'=> '用户'], function($user){
$user->name=
"<a target='_blank' href='". route('users.show', $user->id). "'>".
"<img class='img-thumbnail' width='30px' src='".
$user->avatar ."'> ".
$user->name.
"</a>";
})
;
以上回调函数格式化name字段,将用户名转换成链接,并且添加了一个用户头像。这个回调函数的写法与需要添加页码的回调比起来,简单了很多。
需要加入内联表格的页面越多,就越有必要使用relate(..)函数,真的很方便!
安装
composer require zhaiduting/column-relation
加载
在文件 app\Admin\bootstrap.php 中添加如下代码加载扩展
use Encore\Admin\Grid\Column;
use Zhaiduting\ColumnRelation\Relate;
Column::extend('relate', Relate::class);
加载之后就可以在admin控制器里面使用relate()函数了,用法前面已经说了。
以下2020.2.9内容,不使用relate()函数的写法
经过数日摸索,终于找到了行展开后的表格添加页码的方法。效果如gif动画所示
相关代码如下,其中回调函数的写法相当繁琐
protected function grid()
{
$grid = new Grid(new Role());
$grid->column('id', 'ID');
$grid->column('name', '角色名称')
->expand(function($model){
$users= $model->users()
->paginate(2, ['*'], 'row'. $this->id)
->appends('page', request('page'));
$pagination= $users->toHtml(); //或者 $users->links()
$array= $users->map(function($user){
$user->name=
"<a target='_blank' href='". route('users.show', $user->id). "'>".
"<img class='img-thumbnail' width='30px' src='".
$user->avatar ."'> ".
$user->name.
"</a>";
return $user->only(['id', 'name']);
})->toArray();
$array[]['id']= $pagination; //追加分页代码到新行的第一列
return new Table(['id', '用户名'], $array);
});
$grid->column('permissions', '权限')->pluck('name')->label('default');
$grid->paginate(6);
return $grid;
}
行展开的关键代码是$grid->column(..)->expand(function($model){..})
,这里面涉及到一个回调函数。分页按钮、数据格式化功能就是通过这个回调函数实现的。
1、链接http://w.bbs.cc/admin/roles?page=2&row11=2
表示的是第2页、id为11的数据。
由于这是一个多栏分页的页面,分页参数彼此不能冲突,所以采用了 row1、row2、…这样的分页参数。paginate(2, ['*'], 'row'. $this->id)
主要解决的就是这个参数冲突问题。
2、仅仅解决参数冲突问题还不够,还必须附带添加外层表格的分页参数,appends('page', request('page'))
解决的就是参数附加问题。
3、$pagination= $users->toHtml();
将前面定制好的分页代码提取出来。
4、$array[]['id']= $pagination;
将提取出来的分页代码伪装成新行,添加到内联表格里面。这样页面就可以成功显示分页按钮了!
5、在expand()的回调函数内部有一个数组映射的回调函数,$users->map(function($user){..})
,这个函数里面实现了格式化功能(显示用户头像并添加跳转链接)。
感觉代码写得很粗糙,尤其是$user->name的替换操作更是麻烦。如果大家有更加优雅的写法,敬请分享一下,谢谢!
这里面还有个令人不爽的大问题:点击分页按钮后,之前原本展开的行没能保持展开状态。求解!
另外,将分页代码添加到新行的话,可能需要设置colspan="2"
这样的属性,也不知道怎么添加进去。
【以上2.9日提问,2.16已解】
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: