是否有像这样的Laravel分页?

时间:2018-04-21 07:41:00

标签: php laravel api pagination

我在Laravel框架分页中有一个非常具体的案例。

想象一下,我通过传递偏移量和限制参数从Redis API获取结果。换句话说,分页内容是在API端完成的。 现在,当我在Laravel应用程序中获得结果时,我想以分页方式显示它们。我的意思是一个简单的分页视图,提供导航到其他页面。例如,第二页表示我必须向Redis API发送请求以获取第二组数据。

基于我对Laravel paginator类的理解,它需要一组项目并为它们提供方便的分页。与我想要的东西有点不同。

我只需要一个Class来制作分页视图,该视图将项目总数作为参数并进行相应的链接布局。

在Laravel有一个方便的方法吗? 要么 是我自己实现的唯一选择吗?

1 个答案:

答案 0 :(得分:2)

我正在使用下面的类来使用数据获取分页数据: -

namespace App\Helpers;

use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Collection;
use Countable;
use ArrayAccess;
use ArrayIterator;
use JsonSerializable;
use IteratorAggregate;
use Illuminate\Pagination\LengthAwarePaginator;

class LengthAwareOffsetPaginator extends  LengthAwarePaginator implements
Arrayable,
ArrayAccess,
Countable,
IteratorAggregate,
JsonSerializable,
Jsonable
{
    protected $items;

    protected $total;

    protected $total_pages;

    protected $limit;

    protected $offset;

    protected $options;

    /**
     * LengthAwareOffsetPaginator constructor.
     *
     * @param Collection $items
     * @param $total
     * @param $limit
     * @param $offset
     * @param array $options
     */
    public function __construct(Collection $items, $total, $limit, $offset, array $options = [])
    {
        $this->items = $items;

        if ($items->count() > $limit) {
            $this->items = $items->take($limit);
        }

        $this->total = $total;

        $this->limit = $limit;
        $this->offset = $offset;
        $this->options = $options;

        $this->total_pages = ($total/$limit);
    }

    /**
     * Get url of an offset.
     *
     * @param int $offset
     *
     * @return string Url of an offset
     */
    public function url($pageNumber)
    {
        $query = isset($this->options['queryParameter']) ? $this->options['queryParameter'] : [];

        $offset = ($pageNumber - 1) * $this->limit;
        $query = array_merge($query, ['page' => ['limit' => $this->limit, 'offset' => $offset]]);
        $url = isset($this->options['path']) ? $this->options['path'] : '/';

        return $url.'?'.http_build_query($query);
    }

    /**
     * Get last page.
     *
     * @return int Last page
     */
    public function lastPage()
    {
        $totalPages = ceil($this->total / $this->limit);
        return $totalPages;
    }

    /**
     * Get last page offset.
     *
     * @return int Last page offset
     */
    public function totalPages()
    {
        return $this->total_pages;
    }

    /**
     * Get current page.
     *
     * @return int Last page offset
     */
    public function currentPage()
    {
        $pages = (int)ceil($this->offset / $this->limit);

        $currentPage = ($pages + 1);

        return $currentPage;
    }

    public function perPage()
    {
        return $this->limit;
    }

    /**
     * Get last page url.
     *
     * @return string
     */
    public function lastPageUrl()
    {
        $last = $this->lastPage();

        return $this->url($last);
    }

    /**
     * get next page url.
     *
     * @return string
     */
    public function nextPageUrl()
    {
        $nextOffset = $this->offset + $this->limit;

        return ($nextOffset >= $this->total)
            ? null
            : $this->url($nextOffset);
    }

    /**
     * get previous page url.
     *
     * @return string
     */
    public function previousPageUrl()
    {
        if ($this->offset == 0) {
            return null;
        }

        $prevOffset = $this->offset - $this->limit;

        return ($prevOffset < 0)
            ? $this->url($prevOffset + $this->limit - $this->offset)
            : $this->url($prevOffset);
    }

    public function items()
    {
        return $this->items;
    }

    /**
     * get total items.
     *
     * @return int
     */
    public function total()
    {
        return $this->total;
    }

    /**
     * Get the number of items for the current page.
     *
     * @return int
     */
    public function count()
    {
        // return $this->total;
        return $this->items->count();
    }

    /**
     * Get an iterator for the items.
     *
     * @return \ArrayIterator
     */
    public function getIterator()
    {
        return new ArrayIterator($this->items->all());
    }

    /**
     * Determine if the given item exists.
     *
     * @param mixed $key
     *
     * @return bool
     */
    public function offsetExists($key)
    {
        return $this->items->has($key);
    }

    /**
     * Get the item at the given offset.
     *
     * @param mixed $key
     *
     * @return mixed
     */
    public function offsetGet($key)
    {
        return $this->items->get($key);
    }

    /**
     * Set the item at the given offset.
     *
     * @param mixed $key
     * @param mixed $value
     */
    public function offsetSet($key, $value)
    {
        $this->items->put($key, $value);
    }

    /**
     * Unset the item at the given key.
     *
     * @param mixed $key
     */
    public function offsetUnset($key)
    {
        $this->items->forget($key);
    }

    /**
     * Get the instance as an array.
     *
     * @return array
     */
    public function toArray()
    {
        return [
            'first' => $this->url(0),
            'last' => $this->lastPageUrl(),
            'next' => $this->nextPageUrl(),
            'prev' => $this->previousPageUrl(),
            'data' => $this->items->toArray(),
        ];
    }

    /**
     * Convert the object into something JSON serializable.
     *
     * @return array
     */
    public function jsonSerialize()
    {
        return $this->toArray();
    }

    /**
     * Convert the object to its JSON representation.
     *
     * @param int $options
     *
     * @return string
     */
    public function toJson($options = 0)
    {
        return json_encode($this->jsonSerialize(), $options);
    }
}

你需要这样称呼:

$options['queryParameter'] = [
    'page' => [
        'limit' => 10,
        'offset' => 0
    ],
    'path' => \Illuminate\Pagination\Paginator::resolveCurrentPath()
];
$result = new LengthAwareOffsetPaginator(
    collect($data),
    $totalItemsCount,
    $this->limit,
    $this->offset,
    $options
);

这将为您提供以下输出:

{
  "data": [
    {
        ....
    },
    {
        ....
    }
  ],
  "meta": {
    "pagination": {
      "total": 110,
      "count": 10,
      "per_page": 10,
      "current_page": 1,
      "total_pages": 11,
      "links": [
           "self": "url/pages?page=1",
           "next": "url/pages?page=2",
           "first": "url/pages?page=1",
           "last": "url/pages?page=11"
      ]
    }
  }
}

我认为这会对你有帮助。