在Symfony中使用分页类的正确方法

时间:2016-03-21 12:45:33

标签: symfony pagination symfony-2.3 knppaginator

我正在尝试使用这个Symfony包: https://github.com/KnpLabs/KnpPaginatorBundle

在文档中,他们使用它作为控制器。因此,他们可以轻松访问服务容器或请求对象。

但据我了解,Doctrine查询应该在存储库中,而不是控制器,对吧?我已经有一个函数返回记录。只是分页服务在实例化时不期望“结果”。它想要查询。所以我不能将“结果”返回给控制器,而是在这个函数的中间使用一个分页器。

另一方面,玩服务或请求的东西确实属于控制器。

那应该怎么做呢?起初我想过将“knp_paginator”服务和请求对象注入存储库。但我认为这不是正确的方法。

3 个答案:

答案 0 :(得分:1)

假设您有一个Custom Repository Class,,您可以在该Repository中拥有一个方法,该方法返回Query或Query Builder的有效实例,然后从控制器调用该方法并将其传递给{{1方法。

答案 1 :(得分:1)

我会说Request对象不应该远离堆栈而不是Controller。

没有什么可以阻止您将paginator直接注入自定义存储库,为什么不这样做?

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"]]

在存储库中,您应该有可用于QueryBuilder的分页器:

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

...

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

为了将$page$limit变量放入存储库,您不需要Request对象。只需将它们作为参数传递给存储库调用:

// 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);

将请求对象进一步向下传递意味着您的抽象中存在泄漏。您的应用程序无需了解Request对象。实际上,请求可能来自其他来源,例如CLI命令。由于抽象级别错误,您不希望从那里创建Request对象。

答案 2 :(得分:1)

例如,自定义存储库返回$ qb(不返回结果,只返回它的查询构建器)

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