繁体   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