Laravel 列排序以及分頁範例

效果

安裝 kyslik/column-sortable

此包可用於 Laravel 5/6/7/8

composer

composer require kyslik/column-sortable

手動安裝(laravel 5.5 之前版本)

config/app.php添加服務提供者

'providers' => [

App\Providers\RouteServiceProvider::class,

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

發佈配置

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

用法

In Model

在你想使用排序的model使用Sortable
,將要使用排序欄位定義在$sortable陣列當中

<?php

namespace App\Models;

use Kyslik\ColumnSortable\Sortable;

class Product extends Model
{
use Sortable;

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

}

提醒: Sortable trait 為模型添加了 Sortable 範圍,因此您可以將其與分頁一起使用。

在 樣板 Blade

Blade 中使用@sortablelink()

@sortablelink('column', 'Title', ['parameter' => 'smile'],  ['rel' => 'nofollow'])
  1. 第一個參數: 要排序的欄位名稱
  2. 第二個參數: 在前端要顯示的名稱
  3. 第三個參數: Http GET 默認查詢字符串參數?parameter=smile
  4. 第四個參數: 可以在第 4 個參數中使用自定義 URL 作為 ‘href’ 屬性,查詢字符串將附加到它。此範例會將rel="nofollow"附加在a tag

可以省略第二,第三,第四個參數

官方提供可能使用範例與情境

@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')])

可以設置應用於標題(第二個參數)的默認格式功能,默認情況下設置為ucfirst

簡單的配置

config > columnsortable.php

表格中有為可排序連結區分類型(數字、數量和 alpha),並為每種類型應用不同的類,可以自行新增或修改對應的icon

'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

Font Awesome 5

更改正序倒序的 icon,將配置文件中的後綴類分別從 -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',

如未發布配置文件請參考發佈配置

完整範例

Routes

Route::get('/products', 'App\Http\Controllers\ProductController@index');

Controller

public function index()
{
$products = Product::sortable()->paginate(2);
return view('products', compact('products'));
}

View(包括分頁)

@sortablelink('id', '產品ID')
@sortablelink('name', '名稱')
@sortablelink('created_at', '創建日期')

@foreach ($products as $product)
{{ $product->id }}
{{ $product->name }}
{{ $product->created_at }}
@endforeach

{{-- 此為分頁 --}}
{!! $users->appends(\Request::except('page'))->render() !!}

注意:Blade 識別指令的能力取決於指令本身之前的空格 \ @sortablelink(‘Name’)

HasOne / BelongsTo 關聯排序

定義 hasOne 關聯

要使用關聯排序,需要先在 model 定義hasOne()關聯

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

定義 BelongsTo 關聯

如果有自引用模型(如評論、類別等);父表將使用 parent_ 字符串作為別名,有關更多信息,請參閱issue #60

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

定義$sortable 陣列

在兩個模型中定義 $sortable 數組(否則,package 使用 Scheme::hasColumn() 這是一個額外的數據庫查詢)

User Model

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

UserDetail Model

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

Blade 的關聯排序

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

這裡使用的是在模型中定義的關係“名稱”(方法)而不是使用表名稱。

不要同時使用兩個不同關係的組合,你會得到關係未定義的錯誤

預設使用.做為關聯預設符號,如果.不是你想要的可以到配置文件中修改

'uri_relation_column_separator' => '.'

ColumnSortable overriding (advanced)

可以覆蓋 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.*');
}
...

controller 中一樣使用$users = $user->sortable()->paginate(10);

在 view 中@sortablelink('address')

捕捉異常 try catch

ColumnSortableException使用三個代碼(0、1、2)拋出自定義異常 。

代碼 0 表示explode() 無法將 URI 參數“排序”分解為兩個值。例如:sort=detail..phone_number - 生成大小為 3 的數組,這會導致 package 拋出代碼為 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);
}