[英]Pagination with Eloquent-5.3 using Slim 3
這是我的分頁代碼:
控制器:
public function index($request, $response) {
$current_page = $request->getParam('page');
Paginator::currentPageResolver(function() use ($current_page) {
return $current_page;
});
$routes = $this->route->paginate(2);
return $this->view->render($response, 'dashboard/dashboard.twig', [
'routes' => $routes
]);
}
視圖:
{% for route in routes %}
{{ route.route_name }}<br>
{% endfor %}
當我運行瀏覽器時沒有問題。 當我在網址中添加page
參數時,它也有效。
但是當我嘗試在paginate對象中添加links
方法時。
{% for route in routes %}
{{ route.route_name }}<br>
{% endfor %}
{{ routes.links() }} {# <--- This one #}
它提示我一個錯誤
消息:在null上調用成員函數make()
文件:C:\\ xampp \\ htdocs ... \\ vendor \\ illuminate \\ pagination \\ LengthAwarePaginator.php
更新:
當我嘗試回顯Controller內的links()
方法時。 我發現了這個錯誤。
$routes = $this->route->paginate(5);
echo $routes->links();
die();
警告:call_user_func()期望參數1是有效的回調,沒有在第377行的C:\\ xampp \\ htdocs ... \\ vendor \\ illuminate \\ pagination \\ AbstractPaginator.php中給出的數組或字符串
然后我檢查了源代碼,就是這個。
/**
* Get an instance of the view factory from the resolver.
*
* @return \Illuminate\Contracts\View\Factory
*/
public static function viewFactory()
{
return call_user_func(static::$viewFactoryResolver);
}
對此有何解決方案?
這個方法適用於5.2,參考這個鏈接。
但不幸的是,它不再起作用了。
在PHP 7中,您可以創建匿名類以注冊它以在viewVactory中使用:
$view = $this->container->get('view');
$view->getEnvironment()->addTest(new Twig_SimpleTest('string', function($value) {
return is_string($value);
}));
\Illuminate\Pagination\Paginator::viewFactoryResolver(function() use ($view) {
return new class($view) {
private $view;
private $template;
private $data;
public function __construct(\Slim\Views\Twig $view)
{
$this->view = $view;
}
public function make(string $template, $data = null)
{
$this->template = $template;
$this->data = $data;
return $this;
}
public function render()
{
return $this->view->fetch($this->template, $this->data);
}
};
});
\Illuminate\Pagination\Paginator::currentPageResolver(function() use ($request) {
return $request->getParam('page');
});
return $view->render($response, 'list.twig', [
'items' => Material::paginate(10),
]);
在list.twig
:
{{ items.render('pagination.twig') | raw }}
在pagination.twig
:
{% if paginator.hasPages() %}
<ul class="pagination">
{% for element in elements %}
{% if element is string %}
<li class="disabled"><span>{{ element }}</span></li>
{% endif %}
{% if element is iterable %}
{% for page, url in element %}
{% if page == paginator.currentPage() %}
<li class="active"><span>{{ page }}</span></li>
{% else %}
<li><a href="{{ url }}">{{ page }}</a></li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
</ul>
{% endif %}
我不得不使用上面的答案組合來完成一些工作。 我會在這里發布我的解決方案,以防它幫助別人。
這是Wesley的模板,但升級為使用bootstrap 4.作為獎勵,它不需要中間件來設置任何全局變量。
// pagination.twig
{% if data is not empty and data.lastPage > 1 %}
{# Pagination shows a "window" of links to the left and right of the current page #}
{% set num_visible_pages = 20 %}
<ul class="pagination">
<li class="page-item {{ (data.currentPage == 1) ? 'disabled' : '' }}">
<a class="page-link" href="{{ data.url(1) }}">First</a>
</li>
{% for page_number in 1..(data.lastPage) %}
{% set half_visible_links = num_visible_pages / 2 | round %}
{% set from = data.currentPage - half_visible_links %}
{% set to = data.currentPage + half_visible_links %}
{# if near beginning of pages, extend end to ensure num_visible_pages are shown #}
{% if data.currentPage < half_visible_links %}
{# we can be sloppy because the loop iteration constrains-out-of-bounds values #}
{% set to = (half_visible_links - data.currentPage) + to %}
{% endif %}
{# if near end of pages, extend beginning to ensure num_visible_pages are shown #}
{% if (data.lastPage - data.currentPage) < half_visible_links %}
{# we can be sloppy because the loop iteration constrains-out-of-bounds values #}
{% set from = data.lastPage - num_visible_pages %}
{% endif %}
{# only print pages between "from" and "to" #}
{% if from < page_number and page_number < to %}
<li class="page-item {{ (data.currentPage == page_number) ? 'active' : '' }}">
<a class="page-link" href="{{ data.url(page_number) }}">{{ page_number }}</a>
</li>
{% endif %}
{% endfor %}
<li class="page-item {{ (data.currentPage == data.lastPage) ? 'disabled' : '' }}">
<a class="page-link" href="{{ data.url(data.lastPage) }}">Last</a>
</li>
</ul>
{% endif %}
你可以在你的twig模板中調用這樣的東西,其中“items”是paginator查詢的結果。
{% include 'pagination.twig'
with {data: items} only
%}
然后,你需要告訴Eloquent Paginator如何從網址獲取“頁面”(否則你將被困在第1頁)。 您可以通過在paginator()查詢之前調用currentPageResolver()來執行此操作。 對我來說,我只是把它放到一些中間件中,所以它總是被定義。
<?php
/**
* Tells the Eloquent Paginator how to get the current page
*/
namespace App\Middleware;
class Pagination {
public function __invoke($request, $response, $next)
{
\Illuminate\Pagination\Paginator::currentPageResolver(function() use ($request) {
return $request->getParam('page');
});
return $next($request, $response);
}
}
讓Slim在您的應用設置中了解它的中間件。
$app->add(new App\Middleware\Pagination);
您可能希望向網址添加更多參數,例如排序或切換數據。 您仍然可以使用$items->appends()
來執行此操作。 請注意,默認路徑為“/”。 您可以使用$items->withPath('')
刪除它,因此使用->url()
生成的->url()
將鏈接到當前頁面。
作為臨時解決方案,我似乎可以訪問paginate對象的方法。 所以我試圖在互聯網上找到一個分頁的laravel模板。
這是我提出的解決方案。
它的作用是,它只顯示數組是否為空,顯然它是否呈現多個頁面。 (取決於您在分頁中設置的頁數)
我從某個地方獲得的模板具有適合我需要的修改功能。
{% if arrays is not empty and arrays.lastPage > 1 %}
<div class="paginate-wrapper">
<ul class="pagination">
<li class="{{ (arrays.currentPage == 1) ? 'active' : '' }}">
<a href="{{ uri.link }}{{ (uri.request_sent) ? '&' : '?' }}page=1">First</a>
</li>
{% for page_number in 1..(arrays.lastPage) %}
{% set half_total_links = 7 / 2 | round %}
{% set from = arrays.currentPage - half_total_links %}
{% set to = arrays.currentPage + half_total_links %}
{% if arrays.currentPage < half_total_links %}
{% set to = (half_total_links - arrays.currentPage) + to %}
{% endif %}
{% if (arrays.lastPage - arrays.currentPage) < half_total_links %}
{% set from = (half_total_links - (arrays.lastPage - arrays.currentPage) - 1) - to %}
{% endif %}
{% if from < page_number and page_number < to %}
<li class="{{ (arrays.currentPage == page_number) ? 'active' : '' }}">
<a href="{{ uri.link }}{{ (uri.request_sent) ? '&' : '?' }}page={{ page_number }}">{{ page_number }}</a>
</li>
{% endif %}
{% endfor %}
<li class="{{ (arrays.currentPage == arrays.lastPage) ? 'active' : '' }}">
<a href="{{ uri.link }}{{ (uri.request_sent) ? '&' : '?' }}page={{ arrays.lastPage }}">
Last
</a>
</li>
</ul>
</div>
{% endif %}
這是我在路由器上的中間件。
namespace App\Middleware;
use Illuminate\Database\Capsule\Manager as DB;
use App\Models\Module\Module;
class RouterMiddleware extends Middleware {
public function __invoke($request, $response, $next) {
$uri = $request->getUri();
$current_path = $uri->getPath();
$route = $request->getAttribute('route');
if ($route) {
$route_name = $route->getName();
$uri_page_parameter = $request->getParam('page');
// We want to retrieve the whole url including all the get parameters to get the current url itself
// Excluding page (pagination) parameter.
if ($uri_page_parameter != '') {
$uri = str_replace(['?page=' . $uri_page_parameter, '&page=' . $uri_page_parameter], '', $uri);
}
// We'll also check if the request has been sent using get method
$uri_request_sent = explode('?', $uri);
// Route Information
$this->container->view->getEnvironment()->addGlobal('uri', [
'link' => $uri,
'request_sent' => (isset($uri_request_sent[1])) ? true : false
]);
$this->container->view->getEnvironment()->addGlobal('current_route', $route_name);
$this->container->view->getEnvironment()->addGlobal('current_path', $current_path);
}
$response = $next($request, $response);
return $response;
}
}
它的作用是,每次搜索某些內容時,當您更改頁面時,您發送的所有請求都不會消失。
在你的控制器中,你可以這樣做:
$routes = $this->route->paginate(5);
$window = Illuminate\Pagination\UrlWindow::make($routes);
$elements = [
$window['first'],
is_array($window['slider']) ? '...' : null,
$window['slider'],
is_array($window['last']) ? '...' : null,
$window['last'],
];
// $this->twig is an instance of \Twig_Environment
// before render the template below, you should add `is_array` and `is_string` funcion to twig first
$this->twig->addFunction('is_string', new \Twig_SimpleFunction('is_string', function ($val) {
return is_string($val);
}));
$this->twig->addFunction('is_array', new \Twig_SimpleFunction('is_array', function ($val) {
return is_array($val);
}));
echo $this->twig->render(
'pageNav.html',
['paginator' => $routes, 'elements' => array_filter($elements)]
);
您的模板文件(pageNav.html)將如下所示:
{% if paginator.hasPages %}
<ul class="am-pagination">
{% if paginator.onFirstPage %}
<li class="am-disabled"><span>«</span></li>
{% else %}
<li><a href="{{ paginator.previousPageUrl }}" rel="prev">«</a></li>
{% endif %}
{% for element in elements %}
{% if is_string(element) %}
<li class="am-disabled"><span>{{ element }}</span></li>
{% endif %}
{% if is_array(element) %}
{% for page, url in element %}
{% if paginator.currentPage == page %}
<li class="am-active"><span>{{ page }}</span></li>
{% else %}
<li><a href="{{ url }}">{{ page }}</a></li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% if paginator.hasMorePages %}
<li><a href="{{ paginator.nextPageUrl }}" rel="next">»</a></li>
{% else %}
<li class="am-disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
祝好運:)
有一點問題:
{% if (data.lastPage - data.currentPage) < half_total_links %}
{% set from = (half_total_links - (data.lastPage - data.currentPage) - 1) - to %}
{% endif %}
當data.lastPage
和data.currentPage
相等時,變量from
為負數。
我修好了:
{% if from < 0 %}
{% set from = pagination.page - half_total_links %}
{% endif %}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.