پایگاه داده: صفحه بندی
- معرفی
- استفاده پایه
- نمایش نتایج صفحه بندی
- سفارشی کردن نمای صفحه بندی
- روشهای نمونه Paginator و LengthAwarePaginator
- روشهای نمونه صفحهنمای مکاننما
معرفی
در چارچوب های دیگر، صفحه بندی می تواند بسیار دردناک باشد. امیدواریم رویکرد لاراول به صفحهبندی، نفسی تازه باشد. صفحهبندی لاراول با سازنده پرس و جو و ORM Eloquent یکپارچه شده است و صفحهبندی راحت و آسان رکوردهای پایگاه داده را با پیکربندی صفر فراهم میکند.
بهطور پیشفرض، HTML ایجاد شده توسط صفحهبندیکننده با چارچوب Tailwind CSS سازگار است . با این حال، پشتیبانی از صفحه بندی بوت استرپ نیز در دسترس است.
Tailwind JIT
اگر از نماهای صفحهبندی پیشفرض Tailwind لاراول و موتور JIT Tailwind استفاده میکنید، باید مطمئن شوید که
tailwind.config.js
فایلهای برنامه شما
content
به نماهای صفحهبندی لاراول ارجاع دارند تا کلاسهای Tailwind آنها پاک نشود:
content: [ './resources/**/*.blade.php', './resources/**/*.js', './resources/**/*.vue', './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',],
استفاده پایه
صفحه بندی نتایج سازنده پرس و جو
روش های مختلفی برای صفحه بندی آیتم ها وجود دارد. ساده ترین روش استفاده از
paginate
متد در
سازنده پرس و جو
یا
پرس و جوی Eloquent
است . این
paginate
روش به طور خودکار از تنظیم "محدود" و "offset" درخواست بر اساس صفحه فعلی که توسط کاربر مشاهده می شود، مراقبت می کند. به طور پیش فرض، صفحه فعلی با مقدار آرگومان
page
رشته پرس و جو در درخواست HTTP شناسایی می شود. این مقدار بهطور خودکار توسط لاراول شناسایی میشود و همچنین بهطور خودکار در لینکهای تولید شده توسط صفحهنماگر درج میشود.
در این مثال، تنها آرگومان ارسال شده به
paginate
متد، تعداد مواردی است که میخواهید در هر صفحه نمایش داده شوند. در این مورد، اجازه دهید مشخص کنیم که می خواهیم
15
موارد را در هر صفحه نمایش دهیم:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use Illuminate\Support\Facades\DB;use Illuminate\View\View; class UserController extends Controller{ /** * Show all application users. */ public function index(): View { return view('user.index', [ 'users' => DB::table('users')->paginate(15) ]); }}
صفحه بندی ساده
این
paginate
روش، تعداد کل رکوردهای مطابق با پرس و جو را قبل از بازیابی رکوردها از پایگاه داده شمارش می کند. این کار به این دلیل انجام می شود که صفحه بندی کننده بداند در مجموع چند صفحه رکورد وجود دارد. با این حال، اگر قصد ندارید تعداد کل صفحات را در رابط کاربری برنامه خود نشان دهید، پرس و جو تعداد رکوردها غیر ضروری است.
بنابراین، اگر فقط نیاز دارید که پیوندهای ساده «بعدی» و «قبلی» را در رابط کاربری برنامهتان نمایش دهید، میتوانید از این
simplePaginate
روش برای انجام یک پرس و جوی کارآمد استفاده کنید:
$users = DB::table('users')->simplePaginate(15);
صفحه بندی نتایج شیوا
همچنین می توانید پرس و جوهای
Eloquent
را صفحه بندی کنید . در این مثال، مدل را صفحه بندی می کنیم
App\Models\User
و نشان می دهیم که قصد داریم 15 رکورد در هر صفحه نمایش دهیم. همانطور که می بینید، نحو تقریباً با صفحه بندی نتایج سازنده پرس و جو یکسان است:
use App\Models\User; $users = User::paginate(15);
البته، میتوانید
paginate
متد را پس از تعیین محدودیتهای دیگر روی کوئری فراخوانی کنید، مانند
where
بندهای:
$users = User::where('votes', '>', 100)->paginate(15);
همچنین میتوانید
simplePaginate
هنگام صفحهبندی مدلهای Eloquent از این روش استفاده کنید:
$users = User::where('votes', '>', 100)->simplePaginate(15);
به طور مشابه، می توانید از
cursorPaginate
روش برای صفحه بندی مدل های Eloquent استفاده کنید:
$users = User::where('votes', '>', 100)->cursorPaginate(15);
چندین نمونه صفحهکننده در هر صفحه
گاهی اوقات ممکن است لازم باشد دو صفحهنمای جداگانه را در یک صفحه که توسط برنامه شما ارائه میشود، رندر کنید. با این حال، اگر هر دو نمونه صفحهبندیکننده از
page
پارامتر رشته query برای ذخیره صفحه فعلی استفاده کنند، دو صفحهکننده با هم تضاد خواهند داشت. برای حل این تضاد، می توانید نام پارامتر رشته پرس و جو را که می خواهید برای ذخیره صفحه فعلی صفحه بندی کننده از طریق آرگومان سوم ارائه شده به متدهای،
paginate
و
simplePaginate
و ارسال کنید
cursorPaginate
:
use App\Models\User; $users = User::where('votes', '>', 100)->paginate( $perPage = 15, $columns = ['*'], $pageName = 'users');
صفحه بندی مکان نما
در حالی که
paginate
و
simplePaginate
با استفاده از عبارت "offset" SQL پرس و جو ایجاد می کند، صفحه بندی مکان نما با ساخت بندهای "where" کار می کند که مقادیر ستون های مرتب شده موجود در پرس و جو را مقایسه می کند و کارآمدترین عملکرد پایگاه داده موجود را در بین تمام روش های صفحه بندی لاراول ارائه می دهد. این روش صفحه بندی به ویژه برای مجموعه داده های بزرگ و رابط های کاربری پیمایش "بی نهایت" مناسب است.
بر خلاف صفحهبندی مبتنی بر افست، که شامل یک شماره صفحه در رشته جستجوی URLهای تولید شده توسط صفحهبندی کننده است، صفحهبندی مبتنی بر مکاننما یک رشته «مکاننما» را در رشته جستجو قرار میدهد. مکان نما یک رشته رمزگذاری شده است که حاوی مکانی است که پرس و جوی صفحه بندی شده بعدی باید صفحه بندی را شروع کند و جهتی که باید صفحه بندی شود:
http://localhost/users?cursor=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0
میتوانید یک نمونه صفحهنمای مبتنی بر مکاننما را از طریق
cursorPaginate
روش ارائهشده توسط سازنده پرس و جو ایجاد کنید. این متد یک نمونه از
Illuminate\Pagination\CursorPaginator
:
$users = DB::table('users')->orderBy('id')->cursorPaginate(15);
هنگامی که یک نمونه صفحهبندی مکاننما را بازیابی کردید، میتوانید
نتایج صفحهبندی را
همانطور که معمولاً هنگام استفاده از متدهای
paginate
و نمایش میدهید، نمایش دهید
simplePaginate
. برای اطلاعات بیشتر در مورد روشهای نمونه ارائه شده توسط صفحهنمای مکاننما، لطفاً به
مستندات روش نمونهای صفحهنمای مکاننما
مراجعه کنید .
جستجوی شما باید حاوی یک بند "ترتیب بر اساس" باشد تا از صفحه بندی مکان نما استفاده کنید. علاوه بر این، ستون هایی که پرس و جو بر اساس آنها مرتب شده اند باید متعلق به جدولی باشند که صفحه بندی می کنید.
مکان نما در مقابل صفحه بندی افست
برای نشان دادن تفاوتهای بین صفحهبندی افست و صفحهبندی مکاننما، اجازه دهید چند نمونه پرس و جوی SQL را بررسی کنیم. هر دو پرس و جوی زیر هر دو "صفحه دوم" نتایج را برای یک
users
جدول به ترتیب توسط
id
:
# Offset Pagination...select * from users order by id asc limit 15 offset 15; # Cursor Pagination...select * from users where id > 15 order by id asc limit 15;
پرس و جو صفحه بندی مکان نما مزایای زیر را نسبت به صفحه بندی افست ارائه می دهد:
- برای مجموعه داده های بزرگ، صفحه بندی مکان نما عملکرد بهتری را ارائه می دهد اگر ستون های "ترتیب بر اساس" ایندکس شوند. این به این دلیل است که بند "offset" تمام داده های قبلاً مطابقت شده را اسکن می کند.
- برای مجموعههای داده با نوشتن مکرر، صفحهبندی افست ممکن است رکوردها را رد کند یا موارد تکراری را نشان دهد اگر نتایج اخیراً به صفحهای که کاربر در حال مشاهده آن است اضافه یا از آن حذف شده باشد.
با این حال، صفحه بندی مکان نما دارای محدودیت های زیر است:
-
مانند
simplePaginate
صفحه بندی مکان نما فقط می تواند برای نمایش پیوندهای "بعدی" و "قبلی" استفاده شود و از ایجاد پیوند با شماره صفحه پشتیبانی نمی کند. -
این مستلزم آن است که ترتیب حداقل بر اساس یک ستون منحصر به فرد یا ترکیبی از ستون های منحصر به فرد باشد. ستون های دارای
null
مقادیر پشتیبانی نمی شوند. - عبارات پرس و جو در بندهای "ترتیب بر اساس" فقط در صورتی پشتیبانی می شوند که نام مستعار داشته باشند و به عبارت "انتخاب" نیز اضافه شوند.
- عبارات پرس و جو با پارامترها پشتیبانی نمی شوند.
ایجاد یک صفحهنما به صورت دستی
گاهی اوقات ممکن است بخواهید یک نمونه صفحه بندی را به صورت دستی ایجاد کنید و مجموعه ای از مواردی را که قبلاً در حافظه دارید به آن ارسال کنید.
بسته به نیازتان میتوانید این
کار
را با ایجاد یک یا نمونه انجام دهید
Illuminate\Pagination\Paginator
.
Illuminate\Pagination\LengthAwarePaginator
Illuminate\Pagination\CursorPaginator
نیازی
به دانستن تعداد کل آیتم ها در مجموعه نتیجه نیست
Paginator
.
CursorPaginator
با این حال، به این دلیل، این کلاس ها روشی برای بازیابی فهرست صفحه آخر ندارند.
LengthAwarePaginator
تقریبا همان آرگومانهایی را میپذیرد
که
Paginator
; با این حال، نیاز به شمارش تعداد کل موارد در مجموعه نتیجه دارد.
به عبارت دیگر،
Paginator
مربوط به
simplePaginate
متد در سازنده پرس و جو،
CursorPaginator
مربوط به
cursorPaginate
متد، و
LengthAwarePaginator
مربوط به
paginate
متد است.
هنگامی که به صورت دستی یک نمونه صفحهکننده ایجاد میکنید، باید آرایهای از نتایج را که به صفحهبندیکننده ارسال میکنید، بهصورت دستی «برش» کنید. اگر مطمئن نیستید که چگونه این کار را انجام دهید، تابع array_slice PHP را بررسی کنید.
سفارشی کردن URL های صفحه بندی
بهطور پیشفرض، پیوندهای ایجاد شده توسط صفحهنگار با URI درخواست فعلی مطابقت دارند. با این حال، روش صفحهبندیکننده
withPath
به شما اجازه میدهد تا URI مورد استفاده صفحهکننده را هنگام ایجاد پیوندها سفارشی کنید. به عنوان مثال، اگر می خواهید صفحه بندی کننده پیوندهایی مانند ایجاد کند
http://example.com/admin/users?page=N
، باید
/admin/users
به
withPath
روش زیر بروید:
use App\Models\User; Route::get('/users', function () { $users = User::paginate(15); $users->withPath('/admin/users'); // ...});
افزودن مقادیر رشته کوئری
می توانید با استفاده از روش به رشته پرس و جو پیوندهای صفحه بندی اضافه کنید
appends
. به عنوان مثال، برای الحاق
sort=votes
به هر پیوند صفحه بندی، باید با شماره زیر تماس بگیرید
appends
:
use App\Models\User; Route::get('/users', function () { $users = User::paginate(15); $users->appends(['sort' => 'votes']); // ...});
withQueryString
اگر می خواهید تمام مقادیر رشته پرس و جو درخواست فعلی را به پیوندهای صفحه بندی اضافه کنید،
می توانید از این روش استفاده کنید :
$users = User::paginate(15)->withQueryString();
افزودن قطعات هش
اگر نیاز به اضافه کردن یک "پاره درهم" به URL های تولید شده توسط صفحه بندی کننده دارید، می توانید از این
fragment
روش استفاده کنید. به عنوان مثال، برای الحاق
#users
به انتهای هر پیوند صفحه بندی، باید
fragment
روشی را مانند زیر فراخوانی کنید:
$users = User::paginate(15)->fragment('users');
نمایش نتایج صفحه بندی
هنگام فراخوانی
paginate
متد، نمونه ای از را دریافت خواهید کرد
Illuminate\Pagination\LengthAwarePaginator
، در حالی که فراخوانی
simplePaginate
متد، نمونه ای از را برمی گرداند
Illuminate\Pagination\Paginator
. و در نهایت، فراخوانی
cursorPaginate
متد نمونه ای از
Illuminate\Pagination\CursorPaginator
.
این اشیاء چندین روش ارائه می دهند که مجموعه نتایج را توصیف می کنند. علاوه بر این روش های کمکی، نمونه های صفحه بندی کننده تکرار کننده هستند و ممکن است به عنوان یک آرایه حلقه شوند. بنابراین، هنگامی که نتایج را بازیابی کردید، می توانید نتایج را نمایش دهید و پیوندهای صفحه را با استفاده از Blade ارائه دهید :
<div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach</div> {{ $users->links() }}
این
links
روش پیوندها را به بقیه صفحات در مجموعه نتیجه نمایش می دهد. هر یک از این پیوندها قبلاً حاوی متغیر رشته پرس و جو مناسب هستند
page
. به یاد داشته باشید، HTML تولید شده توسط این
links
روش با
چارچوب Tailwind CSS
سازگار است .
تنظیم پنجره پیوند صفحه بندی
وقتی صفحهبندی پیوندهای صفحهبندی را نمایش میدهد، شماره صفحه فعلی و همچنین پیوندهای سه صفحه قبل و بعد از صفحه فعلی نمایش داده میشود. با استفاده از این
onEachSide
روش، میتوانید کنترل کنید که چه تعداد پیوند اضافی در هر طرف صفحه جاری در پنجره کشویی میانی پیوندهای ایجاد شده توسط صفحهبندی کننده نمایش داده میشود:
{{ $users->onEachSide(5)->links() }}
تبدیل نتایج به JSON
کلاسهای صفحهنمای لاراول
Illuminate\Contracts\Support\Jsonable
قرارداد Interface را پیادهسازی میکنند و
toJson
روش را آشکار میکنند، بنابراین تبدیل نتایج صفحهبندی به JSON بسیار آسان است. همچنین میتوانید یک نمونه صفحهنما را با بازگرداندن آن از یک مسیر یا عملکرد کنترلکننده به JSON تبدیل کنید:
use App\Models\User; Route::get('/users', function () { return User::paginate();});
JSON از صفحهبندی کننده شامل اطلاعات متا مانند
total
،،،
و غیره
current_page
خواهد بود.
last_page
رکوردهای نتیجه از طریق
data
کلید در آرایه JSON در دسترس هستند. در اینجا نمونه ای از JSON ایجاد شده با برگرداندن یک نمونه صفحه بندی از یک مسیر است:
{ "total": 50, "per_page": 15, "current_page": 1, "last_page": 4, "first_page_url": "http://laravel.app?page=1", "last_page_url": "http://laravel.app?page=4", "next_page_url": "http://laravel.app?page=2", "prev_page_url": null, "path": "http://laravel.app", "from": 1, "to": 15, "data":[ { // Record... }, { // Record... } ]}
سفارشی کردن نمای صفحه بندی
به طور پیش فرض، نماهایی که برای نمایش پیوندهای صفحه بندی ارائه می شوند با چارچوب
Tailwind CSS
سازگار هستند . با این حال، اگر از Tailwind استفاده نمیکنید، میتوانید دیدگاههای خود را برای ارائه این پیوندها تعریف کنید. هنگام فراخوانی
links
متد در یک نمونه صفحهبندی، میتوانید نام view را به عنوان اولین آرگومان به متد ارسال کنید:
{{ $paginator->links('view.name') }} <!-- Passing additional data to the view... -->{{ $paginator->links('view.name', ['foo' => 'bar']) }}
با این حال، ساده ترین راه برای سفارشی کردن نماهای صفحه بندی، صادر کردن آنها به
resources/views/vendor
دایرکتوری با استفاده از
vendor:publish
دستور زیر است:
php artisan vendor:publish --tag=laravel-pagination
این دستور view ها را در دایرکتوری برنامه شما قرار می دهد
resources/views/vendor/pagination
. فایل
tailwind.blade.php
درون این فهرست با نمای صفحهبندی پیشفرض مطابقت دارد. شما می توانید این فایل را برای تغییر HTML صفحه بندی ویرایش کنید.
اگر میخواهید فایل دیگری را به عنوان نمای صفحهبندی پیشفرض تعیین کنید، میتوانید صفحهبندیکننده
defaultView
و
defaultSimpleView
متدها را در
boot
متد کلاس خود فراخوانی کنید
App\Providers\AppServiceProvider
:
<?php namespace App\Providers; use Illuminate\Pagination\Paginator;use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * Bootstrap any application services. */ public function boot(): void { Paginator::defaultView('view-name'); Paginator::defaultSimpleView('view-name'); }}
با استفاده از بوت استرپ
لاراول شامل نماهای صفحه بندی است که با استفاده از
Bootstrap CSS
ساخته شده است . برای استفاده از این نماها به جای نماهای پیشفرض Tailwind، میتوانید صفحهبندی
useBootstrapFour
یا
useBootstrapFive
متدهای درون
boot
متد کلاس خود را فراخوانی کنید
App\Providers\AppServiceProvider
:
use Illuminate\Pagination\Paginator; /** * Bootstrap any application services. */public function boot(): void{ Paginator::useBootstrapFive(); Paginator::useBootstrapFour();}
روشهای نمونه Paginator / LengthAwarePaginator
هر نمونه صفحهبندی اطلاعات اضافی صفحهبندی را از طریق روشهای زیر ارائه میکند:
روش | شرح |
---|---|
$paginator->count() |
تعداد موارد صفحه فعلی را دریافت کنید. |
$paginator->currentPage() |
شماره صفحه فعلی را دریافت کنید. |
$paginator->firstItem() |
شماره نتیجه اولین مورد را در نتایج بدست آورید. |
$paginator->getOptions() |
گزینه های صفحه بندی را دریافت کنید. |
$paginator->getUrlRange($start, $end) |
محدوده ای از URL های صفحه بندی ایجاد کنید. |
$paginator->hasPages() |
تعیین کنید که آیا موارد کافی برای تقسیم به چند صفحه وجود دارد یا خیر. |
$paginator->hasMorePages() |
تعیین کنید که آیا موارد بیشتری در فروشگاه داده وجود دارد یا خیر. |
$paginator->items() |
موارد مربوط به صفحه فعلی را دریافت کنید. |
$paginator->lastItem() |
شماره نتیجه آخرین مورد را در نتایج بدست آورید. |
$paginator->lastPage() |
شماره صفحه آخرین صفحه موجود را دریافت کنید. (هنگام استفاده در دسترس نیست
simplePaginate
).
|
$paginator->nextPageUrl() |
آدرس صفحه بعدی را دریافت کنید. |
$paginator->onFirstPage() |
تعیین کنید صفحهبندی در صفحه اول است یا خیر. |
$paginator->perPage() |
تعداد مواردی که باید در هر صفحه نشان داده شود. |
$paginator->previousPageUrl() |
آدرس صفحه قبل را دریافت کنید. |
$paginator->total() |
تعداد کل موارد منطبق را در ذخیرهگاه داده تعیین کنید. (هنگام استفاده در دسترس نیست
simplePaginate
).
|
$paginator->url($page) |
نشانی اینترنتی شماره صفحه معین را دریافت کنید. |
$paginator->getPageName() |
متغیر رشته کوئری مورد استفاده برای ذخیره صفحه را دریافت کنید. |
$paginator->setPageName($name) |
متغیر رشته کوئری مورد استفاده برای ذخیره صفحه را تنظیم کنید. |
$paginator->through($callback) |
هر مورد را با استفاده از پاسخ به تماس تغییر دهید. |
روشهای نمونه صفحهنمای مکاننما
هر نمونه صفحهبندی مکاننما اطلاعات صفحهبندی اضافی را از طریق روشهای زیر فراهم میکند:
روش | شرح |
---|---|
$paginator->count() |
تعداد موارد صفحه فعلی را دریافت کنید. |
$paginator->cursor() |
نمونه مکان نما فعلی را دریافت کنید. |
$paginator->getOptions() |
گزینه های صفحه بندی را دریافت کنید. |
$paginator->hasPages() |
تعیین کنید که آیا موارد کافی برای تقسیم به چند صفحه وجود دارد یا خیر. |
$paginator->hasMorePages() |
تعیین کنید که آیا موارد بیشتری در فروشگاه داده وجود دارد یا خیر. |
$paginator->getCursorName() |
متغیر رشته کوئری مورد استفاده برای ذخیره مکان نما را دریافت کنید. |
$paginator->items() |
موارد مربوط به صفحه فعلی را دریافت کنید. |
$paginator->nextCursor() |
نمونه مکان نما را برای مجموعه آیتم های بعدی دریافت کنید. |
$paginator->nextPageUrl() |
آدرس صفحه بعدی را دریافت کنید. |
$paginator->onFirstPage() |
تعیین کنید صفحهبندی در صفحه اول است یا خیر. |
$paginator->onLastPage() |
تعیین کنید صفحهبندی در آخرین صفحه است یا خیر. |
$paginator->perPage() |
تعداد مواردی که باید در هر صفحه نشان داده شود. |
$paginator->previousCursor() |
نمونه مکان نما را برای مجموعه موارد قبلی دریافت کنید. |
$paginator->previousPageUrl() |
آدرس صفحه قبل را دریافت کنید. |
$paginator->setCursorName() |
متغیر رشته کوئری مورد استفاده برای ذخیره مکان نما را تنظیم کنید. |
$paginator->url($cursor) |
نشانی اینترنتی یک نمونه مکان نما را دریافت کنید. |