簡體   English   中英

使用Slim 3對Eloquent-5.3進行分頁

[英]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,參考這個鏈接。

用Twig和Eloquent-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>&laquo;</span></li>
    {% else %}
    <li><a href="{{ paginator.previousPageUrl }}" rel="prev">&laquo;</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">&raquo;</a></li>
    {% else %}
    <li class="am-disabled"><span>&raquo;</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.lastPagedata.currentPage相等時,變量from為負數。

我修好了:

{% if from < 0 %}
  {% set from = pagination.page - half_total_links %}
{% endif %}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM