nikolaymurha/column-sortable

用于处理 Laravel 6.x 中列排序的包

安装: 34

依赖者: 0

建议者: 0

安全: 0

星星: 0

关注者: 2

分支: 105

类型:package

6.5.0 2022-11-07 20:44 UTC

README

Laravel 5.5-8 的列排序

Latest Version Software License Total Downloads run-tests

用于处理 Laravel 5.[5-8] 的列排序的包。对于更早版本的 Laravel,请检查分支 L5.1-3

设置

Composer

通过 Composer 引入此包(开发/最新版本 dev-master

{
    "require": {
        "kyslik/column-sortable": "^6.0"
    }
}
composer update

Laravel >=5.5 自动发现

简单安装包,让 Laravel 展示其魔法。

注意(5.5 之前):主版本和次版本应与 Laravel 的版本相匹配,例如,如果您正在使用 Laravel 5.4,column-sortable 版本应该是 5.4.*

手动安装(5.5 之前)

将服务提供者添加到 config/app.php 中 providers 数组

'providers' => [

    App\Providers\RouteServiceProvider::class,

    /*
     * Third Party Service Providers...
     */
    Kyslik\ColumnSortable\ColumnSortableServiceProvider::class,
],

发布配置

将包配置文件发布到您的应用程序

php artisan vendor:publish --provider="Kyslik\ColumnSortable\ColumnSortableServiceProvider" --tag="config"

查看配置文件 (config/columnsortable.php) 并根据需要进行调整。

使用方法

在您的 Eloquent 模型(s)内部使用 Sortable 特性。定义 $sortable 数组(请参阅下面的示例代码)。

注意:仅当 $sortable 未定义时才会运行 Scheme::hasColumn() - 每个请求的数据库访问次数更少。

use Kyslik\ColumnSortable\Sortable;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
    use Authenticatable, CanResetPassword, Sortable;
    ...

    public $sortable = ['id',
                        'name',
                        'email',
                        'created_at',
                        'updated_at'];
    ...
}

您已准备就绪。

Sortable 特性向模型添加 Sortable 范围,因此您可以使用它与 paginate 一起使用。

Blade 扩展

有一个 blade 扩展供您使用 @sortablelink()

@sortablelink('column', 'Title', ['parameter' => 'smile'],  ['rel' => 'nofollow'])

(第 1 个)参数是数据库中的列,标题(第 2 个)参数用于锚标签内部显示,array() 参数(第 3 个)是默认(GET)查询字符串参数,array() 参数(第 4 个)是用于附加锚标签属性的。您可以在第 4 个参数中使用自定义 URL 作为 'href' 属性,并将查询字符串附加到它。

您可以省略第 2、3 和 4 个参数。

通过在第 3 个参数中使用 ['direction'=>'desc'],您可以覆盖默认切换行为。

Blade 扩展的可能示例和用法

@sortablelink('name')
@sortablelink('name', 'Username')
@sortablelink('address', trans('fields.address'), ['filter' => 'active, visible'])
@sortablelink('address', trans('fields.address'), ['filter' => 'active, visible'], ['class' => 'btn btn-block', 'rel' => 'nofollow', 'href' => route('my.custom.route')])
@sortablelink(null, 'Reset') {{!-- back to default --}}

如果您不填写 标题(第 2 个参数),则使用列名代替。

注意:您可以为 标题(第 2 个参数)设置默认格式化函数,默认情况下设置为 ucfirst

简要说明配置

Sortablelink blade 扩展区分 类型数值数量字母)并为每个类型应用不同的类。

请参阅以下片段

'columns' => [
    'numeric'  => [
        'rows' => ['created_at', 'updated_at', 'level', 'id'],
        'class' => 'fa fa-sort-numeric'
    ],
    'amount'   => [
        'rows' => ['price'],
        'class' => 'fa fa-sort-amount'
    ],
    'alpha'    => [
        'rows' => ['name', 'description', 'email', 'slug'],
        'class' => 'fa fa-sort-alpha',
    ],
],

其余的 配置文件 应该很清晰,我建议您快速浏览。

Font Awesome(默认字体类)

安装 Font-Awesome 以提供视觉效果。在 cheatsheet 中搜索 "sort",自己查看使用的图标(12)。

Font Awesome 5

将配置文件中的后缀类名从 -asc/-desc(FA 4)分别更改为 -up/-down(FA 5)。

/* this is FA 5 compatible.
suffix class that is appended when ascending direction is applied */
'asc_suffix'                    => '-up',

/* suffix class that is appended when descending direction is applied */
'desc_suffix'                   => '-down',

注意:如果您尚未发布配置,请遵循上面的说明

完整示例

您可能对工作示例仓库感兴趣,其中演示了包的使用。

路由

Route::get('users', ['as' => 'users.index', 'uses' => 'HomeController@index']);

控制器 index() 方法

public function index(User $user)
{
    $users = $user->sortable()->paginate(10);

    return view('user.index')->withUsers($users);
}

您可以为URL为空时应用默认排序参数。

例如:页面第一次加载时,默认方向是可配置的(升序)

$users = $user->sortable('name')->paginate(10);
// produces ->orderBy('users.name', 'asc')

$users = $user->sortable(['name'])->paginate(10); 
// produces ->orderBy('users.name', 'asc')

$users = $user->sortable(['name' => 'desc'])->paginate(10);
// produces ->orderBy('users.name', 'desc')

视图(包含分页)

@sortablelink('id', 'Id')
@sortablelink('name')

@foreach ($users as $user)
    {{ $user->name }}
@endforeach
{!! $users->appends(\Request::except('page'))->render() !!}

注意:Blade能够识别指令,取决于指令前是否有空格 <tr> @sortablelink('Name')

HasOne / BelongsTo 关系排序

定义 hasOne 关系

为了让关系排序工作,您必须在模型中定义 hasOne() 关系。

/**
* Get the user_detail record associated with the user.
*/
public function detail()
{
    return $this->hasOne(App\UserDetail::class);
}

定义 belongsTo 关系

注意:如果存在自引用模型(如评论、分类等),则父表将使用 parent_ 字符串进行别名,更多信息请参见问题 #60

/**
 * Get the user that owns the phone.
 */
public function user()
{
    return $this->belongsTo(App\User::class);
}

User模型中,我们定义了到UserDetail模型(包含电话号码和地址详情)的hasOne关系。

定义 $sortable 数组

在两个模型中定义$sortable数组(否则,包将使用Scheme::hasColumn(),这将产生额外的数据库查询)。

User

public $sortable = ['id', 'name', 'email', 'created_at', 'updated_at'];

UserDetail

public $sortable = ['address', 'phone_number'];

Blade 和关系排序

为了让包使用关系进行排序

@sortablelink('detail.phone_number', 'phone')
@sortablelink('user.name', 'name')

注意:包使用您在模型中定义的“name”(方法)关系,而不是表名。

警告:不要同时使用两个不同的关系,否则您将获得“关系未定义”的错误。

在配置文件中,您可以设置自己的分隔符,如果.(点)不是您想要的。

'uri_relation_column_separator' => '.'

ColumnSortable 覆盖(高级)

可以覆盖ColumnSortable关系功能,基本上您可以编写自己的连接(查询)并手动应用orderBy()

请参阅示例

class User extends Model
{
    use Sortable;

    public $sortable = ['name'];
    ...

    public function addressSortable($query, $direction)
    {
        return $query->join('user_details', 'users.id', '=', 'user_details.user_id')
                    ->orderBy('address', $direction)
                    ->select('users.*');
    }
    ...

控制器相同 $users = $user->sortable()->paginate(10);

在视图中,只需使用 @sortablelink('address')

向@neutralrockets和他的评论#8致以衷心的感谢。关于如何使用覆盖的另一个示例,请参阅问题#41

别名

可以声明$sortableAs数组并使用它来别名(绕过列存在检查),并且忽略以表名开头。

在模型中

...
$sortableAs = ['nick_name'];
...

在控制器中

$users = $user->select(['name as nick_name'])->sortable(['nick_name'])->paginate(10);

在视图中

@sortablelink('nick_name', 'nick')

有关更多信息请参见#44

使用 withCount()

别名在您想要使用withCount()对结果进行排序时很有用,有关更多信息请参阅问题 #49

异常捕获

包抛出自定义异常ColumnSortableException,带有三个代码(0、1、2)。

代码0表示explode()无法将URI参数“sort”拆分为两个值。例如:sort=detail..phone_number - 产生大小为3的数组,导致包抛出代码为0的异常。

代码1表示$query->getRelation()方法失败,这意味着当关系名称无效(不存在,未在模型中声明)时。

代码 2 表示通过排序参数提供的关联不是 hasOne 的实例。

示例如何捕获

...
try {
    $users = $user->with('detail')->sortable(['detail.phone_number'])->paginate(5);
} catch (\Kyslik\ColumnSortable\Exceptions\ColumnSortableException $e) {
    dd($e);
}

注意:我强烈建议捕获 ColumnSortableException,因为用户输入(GET 参数)有问题,任何用户都可以修改它,使得包抛出带有代码 0ColumnSortableException

会话 - 持久化参数

包支持将可排序参数 sortdirection 保存到会话中。为了在应用级别支持此功能,将 to_session 配置参数设置为 true