--- tags: PHP, Laravel, Backend --- # Laravel 列排序以及分頁範例 ## 安裝`kyslik/column-sortable` ==此包適用於Laravel 5/6/7/8== ### composer `composer require kyslik/column-sortable` ### 手動安裝(laravel 5.5之前版本) 在`config/app.php`添加服務提供者 ```php= 'providers' => [ App\Providers\RouteServiceProvider::class, /* * Third Party Service Providers... */ Kyslik\ColumnSortable\ColumnSortableServiceProvider::class, ], ``` ### 發佈配置 `php artisan vendor:publish --provider="Kyslik\ColumnSortable\ColumnSortableServiceProvider" --tag="config"` ## 用法 ### 在Model中使用 在你想使用排序的`model`使用`Sortable` ,將要使用排序的欄位定義在`$sortable`陣列當中 ```php= <?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中 在`laravel Blade`中使用`@sortablelink()` ```php= @sortablelink('column', 'Title', ['parameter' => 'smile'], ['rel' => 'nofollow']) ``` 1. 第一個參數: 要排序的欄位名稱 1. 第二個參數: 在前端要顯示的名稱 1. 第三個參數: Http GET默認查詢字符串參數`?parameter=smile` 1. 第四個參數: 可以在第 4 個參數中使用自定義 URL 作為 'href' 屬性,查詢字符串將附加到它。此範例會將`rel="nofollow"`附加在`a tag`上 可以省略第二,第三,第四個參數 官方提供可能使用範例與情境 ```php= @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')]) ``` :::info 可以設置應用於標題(第二個參數)的默認格式功能,默認情況下設置為[`ucfirst`](https://www.php.net/manual/en/function.ucfirst.php)。 ::: ### 簡單的配置 `config > columnsortable.php` 表格中有為可排序連結區分類型(數字、數量和 `alpha`),並為每種類型應用不同的類,可以自行新增或修改對應的`icon` ```php= '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](https://fontawesome.com/versions) #### Font Awesome 5 更改正序倒序的`icon`,將配置文件中的後綴類分別從 `-asc/-desc (FA 4)` 更改為 `-up/-down (FA 5)`。 ```php= /* 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', ``` :::info 如未發布配置文件請參考[發佈配置](#發佈配置) ::: ## 完整範例 ### Routes `Route::get('/products', 'App\Http\Controllers\ProductController@index');` ### Controller ```php= public function index() { $products = Product::sortable()->paginate(2); return view('products', compact('products')); } ``` ### View(包括分頁) ```blade= @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() !!} ``` :::warning 注意:Blade 識別指令的能力取決於指令本身之前是否有空格 `<tr> @sortablelink('Name')` ::: ### 展示 ![](https://i.imgur.com/14eMW7p.gif) ## HasOne / BelongsTo關聯排序 ### 定義hasOne關聯 要使用關聯排序,需要先在model定義`hasOne()`關聯 ```php= /** * Get the user_detail record associated with the user. */ public function detail() { return $this->hasOne(App\UserDetail::class); } ``` ### 定義BelongsTo關聯 :::info 如果有自引用模型(如評論、類別等);父表將使用 parent_ 字符串作為別名,有關更多信息,請參閱[issue #60](https://github.com/Kyslik/column-sortable/issues/60)。 ::: ```php= /** * 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的關聯排序 ```php= @sortablelink('detail.phone_number', 'phone') @sortablelink('user.name', 'name') ``` :::info 這裡使用的是在模型中定義的關係“名稱”(方法)而不是使用表名稱。 ::: :::warning 不要同時使用兩個不同關係的組合,你會得到關係未定義的錯誤 ::: 預設使用`.`做為關聯預設符號,如果`.`不是你想要的可以到配置文件中修改 ```php= 'uri_relation_column_separator' => '.' ``` ## ColumnSortable overriding (advanced) 可以覆蓋 ColumnSortable 關係功能,基本上您可以編寫自己的連接/查詢並手動應用 orderBy() 範例: ```php= 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 的實例。 捕捉異常範例: ```php= try { $users = $user->with('detail')->sortable(['detail.phone_number'])->paginate(5); } catch (\Kyslik\ColumnSortable\Exceptions\ColumnSortableException $e) { dd($e); } ``` [column-sortable](https://github.com/Kyslik/column-sortable)