it-swarm.com.de

Wie kann ich eine zusammengefügte Sammlung paginieren? Laravel 5?

Ich erstelle einen Stream, der zwei Arten von Objekten enthält, BluePerson und RedPerson. Um den Stream zu erstellen, hole ich alle Objekte ab und füge sie dann in einer Sammlung zusammen. Danach muss ich sie paginieren, obwohl paginate für eloquente Modelle und DB-Abfragen gilt und keine Sammlungen, wie es scheint. Ich habe viel über das manuelle Erstellen eines Paginators gesehen, aber die Dokumentation, vor allem in der API, ist spärlich (ich kann nicht einmal die Argumente finden, die die Paginator-Klasse akzeptiert.) 

Wie kann ich die Ergebnisse des Zusammenführens meiner Sammlungen paginieren?

public function index()
{
    $bluePerson = BluePerson::all();
    $redPerson = RedPerson::all();

    $people = $bluePerson->merge($redPerson)->sortByDesc('created_at');


    return view('stream.index')->with('people', $people);
}
16
KinsDotNet

paginate ist jedoch für eloquente Modelle und DB-Abfragen und nicht für Sammlungen gedacht.

Du hast recht. Es gibt jedoch eine Paginator-Funktion für Sammlungen. forPage

Syntax:

Collection forPage(int $page, int $perPage)

Beispiel:

Der Rest ist einfach. 

public function foo()
{
    $collection = collect([1,2,3,4,5,6,7,8,9,0]);
    $items = $collection->forPage($_GET['page'], 5); //Filter the page var
    dd($items);
}
17
itachi

Wenn Sie einen LengthAwarePaginator verwenden möchten, instanziieren Sie einfach einen. Wie in den Kommentaren einer früheren Antwort erwähnt, müssen Sie den Pfad dafür festlegen. Sie müssen außerdem sicherstellen, dass Sie die "currentPage" auflösen und die Elemente festlegen, die zurückgegeben werden sollen, bevor Sie den Paginator instanziieren. Dies kann alles vor/bei der Instantiierung erfolgen. Eine Funktion kann also wie folgt aussehen:

function paginateCollection($collection, $perPage, $pageName = 'page', $fragment = null)
{
    $currentPage = \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPage($pageName);
    $currentPageItems = $collection->slice(($currentPage - 1) * $perPage, $perPage);
    parse_str(request()->getQueryString(), $query);
    unset($query[$pageName]);
    $paginator = new \Illuminate\Pagination\LengthAwarePaginator(
        $currentPageItems,
        $collection->count(),
        $perPage,
        $currentPage,
        [
            'pageName' => $pageName,
            'path' => \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPath(),
            'query' => $query,
            'fragment' => $fragment
        ]
    );

    return $paginator;
}
25
Michael Holland

Sie können versuchen, beide Sätze zu paginieren und sie zusammenzuführen. Weitere Informationen zur Paginierung finden Sie in den Dokumenten docs und api . Hier ist ein Beispiel für das manuelle Erstellen eines eigenen Paginators ...

$perPage = 20;
$blue = BluePerson::paginate($perPage / 2);
$red = RedPerson::paginate($perPage - count($blue));
$people = PaginationMerger::merge($blue, $red);

Ich habe die PaginationMerger-Klasse unten hinzugefügt.

use Illuminate\Pagination\LengthAwarePaginator;

class PaginationMerger
{
    /**
     * Merges two pagination instances
     *
     * @param  Illuminate\Pagination\LengthAwarePaginator $collection1
     * @param  Illuminate\Pagination\LengthAwarePaginator $collection2
     * @return Illuminate\Pagination\LengthAwarePaginator
     */
    static public function merge(LengthAwarePaginator $collection1, LengthAwarePaginator $collection2)
    {
        $total = $collection1->total() + $collection2->total();

        $perPage = $collection1->perPage() + $collection2->perPage();

        $items = array_merge($collection1->items(), $collection2->items());

        $paginator = new LengthAwarePaginator($items, $total, $perPage);

        return $paginator;
    }
}
6
Kelt

bester Weg für die Paginatensammlung:

1- Fügen Sie dies zur Startfunktion in\app\Providers\AppServiceProvider hinzu

       /*
         * use Illuminate\Support\Collection;
         * use Illuminate\Pagination\LengthAwarePaginator;
         *
         * Paginate a standard Laravel Collection.
         *
         * @param int $perPage
         * @param int $total
         * @param int $page
         * @param string $pageName
         * @return array
         */
        Collection::macro('paginate', function($perPage, $total = null, $page = null, $pageName = 'page') {
            $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
            return new LengthAwarePaginator(
                $this->forPage($page, $perPage),
                $total ?: $this->count(),
                $perPage,
                $page,
                [
                    'path' => LengthAwarePaginator::resolveCurrentPath(),
                    'pageName' => $pageName,
                ]
            );
        });

2-Ab hier können Sie für alle Sammlungen wie Ihren Code paginieren

$people->paginate(5)
2
Rohallah Hatami

Versuchen Sie folgendes.

$arr = $pets->toArray();
$paginator->make($arr, count($arr), $perPage);

Sie können den folgenden Code für Collection in Providers/AppServiceProvider hinzufügen. 

    // Enable pagination
    if (!Collection::hasMacro('paginate')) {

        Collection::macro('paginate', 
            function ($perPage = 15, $page = null, $options = []) {
            $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
            return (new LengthAwarePaginator(
                $this->forPage($page, $perPage)->values()->all(), $this->count(), $perPage, $page, $options))
                ->withPath('');
        });
    }

Dann können Sie aus einer Collection paginate aufrufen, genau wie ein Eloquent-Modell. Zum Beispiel

$pages = collect([1, 2, 3, 4, 5, 6, 7, 8, 9])->paginate(5);
1
dushoda