web-dev-qa-db-fra.com

Symfony 4 - KnpPaginator Bundle "service introuvable, même s'il existe dans le conteneur de l'application"

J'ai suivi des tutoriels, et toutes les instructions montrent que cela se fait exactement de la même manière, mais cela ne semble pas fonctionner dans Symfony 4. Y a-t-il quelque chose que je néglige ou le bundle est-il simplement incompatible?

J'ai couru: composer require knplabs/knp-paginator-bundle

Il a été chargé automatiquement dans bundles.php, grâce à Flex.

Inséré ce qui suit dans config/services.yaml:

knp_paginator:
    page_range:                 5          # default page range used in pagination control
    default_options:
        page_name:              page       # page query parameter name
        sort_field_name:        sort       # sort field query parameter name
        sort_direction_name:    direction  # sort direction query parameter name
        distinct:               true       # ensure distinct results, useful when ORM queries are using GROUP BY statements
    template:
        pagination: KnpPaginatorBundle:Pagination:Twitter_bootstrap_v3_pagination.html.twig     # sliding pagination controls template
        sortable: KnpPaginatorBundle:Pagination:sortable_link.html.twig                         # sort link template

J'ai essayé d'utiliser les éléments suivants dans le contrôleur:

$paginator  = $this->get('knp_paginator');

et a obtenu l'erreur suivante:

Service "knp_paginator" introuvable: même s'il existe dans le conteneur de l'application, le conteneur à l'intérieur de "App\Controller\PhotoController" est un localisateur de service plus petit qui ne connaît que la "doctrine", "form.factory", "http_kernel", Services "request_stack", "router", "security.authorization_checker", "security.token_storage", "serializer", "session" et "twig". Sauf si vous avez besoin d'une paresse supplémentaire, essayez plutôt d'utiliser l'injection de dépendance. Sinon, vous devez le déclarer en utilisant "PhotoController :: getSubscribedServices ()".

8
Darius

Vous devez étendre la classe Controller au lieu de la classe AbstractController:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MyController extends Controller
{

    public function myAction()
    {
        $paginator  = $this->get('knp_paginator');

ou mieux laisser AbstractController et injecter knp_paginator service dans votre action:

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Knp\Component\Pager\PaginatorInterface;

class MyController extends AbstractController
{

    public function myAction(PaginatorInterface $paginator)
    {
        $paginator->paginate()...
    }
22
malcolm

Dans mon cas, j'utilise AbstractController et comme malcolm le dit, il vaut mieux injecter le service directement dans votre action, même ainsi, j'appelle plusieurs fois une méthode et je pense que écraser getSubscribedServices est plus clener pour mon porpuse.

public static function getSubscribedServices(): array
{
    $services = parent::getSubscribedServices();
    $services['fos_elastica.manager'] = RepositoryManagerInterface::class;
    $services['knp_paginator'] = PaginatorInterface::class;

    return $services;
}

private function listHandler(Search $search, Request $request, int $page): Response
{
    //...
    $repository = $this->container->get('fos_elastica.manager')->getRepository(Foo::class);
    //...

}
8
Sfblaauw

Comme il est dit dans la documentation. Vous devez étendre la classe de base Controller ou utiliser l'injection de dépendance à la place https://symfony.com/doc/current/service_container.html#service-parameters

1
Nemus

Dans mon cas, j'utilise symfony 4.3, je viens d'injecter la classe aux méthodes comme argument et j'ai terminé.

public function list(ProductManager $productManager)
{ 
   $products = $productManager->prepareProducts(); 
   return $products;
}
0
sh6210