Laravel Nova 定义 Lenses
与过滤器类似, Nova lenses 允许你充分的定制资源的底层 Eloquent 查询。例如,你可能希望列出所有的应用的用户,并按照总的终生收入来排序。创建这样一个列表可能需要你连接额外的数据表和在查询中执行聚合函数。听起来挺复杂的,但是不要担心 - 这正是 lenses 旨在解决的场景:
刚开始,你需要使用 nova:lens
Artisan 命令。默认情况下,Nova 会把新创建的 lenses 放置在 app/Nova/Lenses
目录下:
php artisan nova:lens MostValuableUsers
每一个 Nova 创建的 Lens 都包含几个方法。然而,目前我们关注的两个方法是 query
和 fields
方法。query
方法负责创建获取所需数据的 Eloquent 查询,而 fields
方法返回了在查看
lens 时应当显示的字段的数组。
为了更深入的学习,我们来看一个完整 lens,该 lens 显示了用户和他们的终生收入:
<?php
namespace App\Nova\Lenses;
use Laravel\Nova\Fields\ID;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Lenses\Lens;
use Laravel\Nova\Fields\Number;
use Illuminate\Support\Facades\DB;
use Laravel\Nova\Http\Requests\LensRequest;
class MostValuableUsers extends Lens
{
/**
* 获取 lens 的查询创建器和分页器
*
* @param \Laravel\Nova\Http\Requests\LensRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return mixed
*/
public static function query(LensRequest $request, $query)
{
return $request->withOrdering($request->withFilters(
$query->select($this->columns())
->join('licenses', 'users.id', '=', 'licenses.user_id')
->orderBy('revenue', 'desc')
->groupBy('users.id', 'users.name')
));
}
/**
* 获取应该选择的列
*
* @return array
*/
protected function columns()
{
return [
'users.id',
'users.name',
DB::raw('sum(licenses.price) as revenue'),
];
}
/**
* 获取 lens 可获取的字段
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function fields(Request $request)
{
return [
ID::make('ID', 'id'),
Text::make('Name', 'name'),
Number::make('Revenue', 'revenue', function ($value) {
return '$'.number_format($value, 2);
}),
];
}
/**
* 获取 lens 可获取的过滤器
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function filters(Request $request)
{
return [];
}
/**
* 获取 lens 的 URI
*
* @return string
*/
public function uriKey()
{
return 'most-profitable-users';
}
}
Columns 方法
在这个例子中,为了可读性,
columns
方法已经从query
方法中分离出来。它不是「必须」的,同时也不是 lenses 的一个 「特性」。
正如你在上面的例子中所见到的, query
方法已经完全控制了获取 lens 数据的 Eloquent 查询。为了让查询返回的数据合理的展示,fields
方法可以改变任何 Nova 的字段。
Lens 过滤器
每一个 Nova lens 都包含一个 filters
方法。这个方法可以让你把任何现存的 过滤器 添加到 lens:
use App\Nova\Filters\UserType;
/**
* 获取 lens 可以获取的过滤器
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function filters(Request $request)
{
return [new UserType];
}
更多建议: