2016-03-21 14 views
0

Ich versuche, dieses Symfony Bündel zu verwenden: https://github.com/KnpLabs/KnpPaginatorBundleDer richtige Weg, um eine Paginierung Klasse in Symfony der Verwendung

In der Dokumentation, sie es verwenden einen Controller. Sie haben also einfachen Zugriff auf den Servicebehälter oder das Anfrageobjekt.

Aber soweit ich verstehe, sollte die Doctrine-Abfrage in einem Repository sein, kein Controller, oder? Und ich habe bereits eine Funktion, die Datensätze zurückgibt. Es ist nur so, dass der Paginierungsdienst beim Instantiieren keine "Ergebnisse" erwartet. Es will die Abfrage. Daher kann ich die "Ergebnisse" nicht zum Controller zurückgeben, sondern benutze einen Paginator in der Mitte dieser Funktion.

Auf der anderen Seite gehören Dinge wie das Spielen mit Diensten oder Anfragen tatsächlich zu Controllern.

Also wie soll das gemacht werden? Zuerst dachte ich darüber nach, den Dienst "knp_paginator" und das Anfrageobjekt in das Repository zu übernehmen. Aber ich denke nicht, dass dies der richtige Weg ist.

Antwort

1

Ich würde sagen, dass das Request-Objekt nicht weiter unten im Stapel als vom Controller gehen sollte.

Nichts hindert Sie daran, den Paginator direkt in Ihr benutzerdefiniertes Repository zu injizieren, also warum nicht?

your.repository.service.definition: 
    class: Your\Repository\Class 

    # for symfony 2.3 
    factory_service: doctrine 
    factory_method: getRepository 

    # for symfony 2.8 and higher 
    factory: ["@doctrine.orm.entity_manager", getRepository] 

    arguments: 
     - YourBundle:YourEntity 
    calls: 
     - [setPaginator, ["@knp_paginator"]] 

Im Repository, sollten Sie dann den paginator für die Querybuilder zur Verfügung haben:

public function setPaginator($paginator) 
{ 
    $this->paginator = $paginator; 
} 

... 

$this->paginator->paginate($qb->getQuery(), $page, $limit); 

Um Ihre $page und $limit Variablen in das Repository zu bekommen, brauchen Sie nicht die Anfrageobjekt gibt ihnen nicht einfach als Parameter in den Repository Aufruf:

// In your controller 
// You can use forms here if you want, but for brevity: 
$criteria = $request->get('criteria'); 
$page = $request->get('page'); 
$limit = $request->get('limit'); 

$paginatedResults = $myCustomRepository->fetchPaginatedData($criteria, $page, $limit); 

das Request-Objekt Passing weiter unten in der Steuerung bedeutet, dass Sie ein Leck in Ihren Abstraktionen haben. Es geht nicht darum, dass Ihre Anwendung das Request-Objekt kennt. Tatsächlich könnte die Anfrage auch aus anderen Quellen wie dem CLI-Befehl stammen. Sie möchten kein Request-Objekt von dort wegen einer falschen Abstraktionsebene erstellen.

+0

Bu Ich brauche das Request-Objekt, um URL-Parameter ($ Anfrage-> Abfrage-> GetInt ('Seite', 1)) zu erhalten, aber ich dachte auch, dass wir dieses Objekt nirgends passieren sollten ... –

+1

Ich habe die bearbeitet Antwort mit weiteren Erläuterungen – hasumedic

+0

Danke @hasumedic! –

1

Unter der Annahme, dass Sie ein Custom Repository Class, Sie eine Methode in diesem Repository haben kann, die eine Abfrage oder eine gültige Instanz von Query Builder gibt und Sie dann von der Steuerung diese Methode aufrufen und an die paginate()-Methode übergeben.

+0

Vielen Dank! –

1

Zum Beispiel, wo $ qb vom benutzerdefinierten Repository zurückgegeben wird (nicht Ergebnis zurück, sondern nur die Querybuilder davon)

$paginator = $this->get('knp_paginator'); 
$pagination = $paginator->paginate(
    $qb->getQuery(), 
    $request->query->getInt($pageParameterName, 1), 
    $perPage, 
    array('pageParameterName' => $pageParameterName) 
);