3

我的 ZF2 应用程序中有一个模块Search。用户填写搜索表格并获得课程列表。

现在我将分页添加到模块中。分页器基本上可以工作:我可以通过它检索数据并且分页显示正确(页面链接 1-7 用于 70 个找到的课程,默认设置为每页 10 个项目)。

但它仍然无法使用。当我单击页面链接时,表单 POST 数据丢失。我知道 - 它无法正常工作,我是如何实现它的(参见下面的代码)。但我不知道如何正确地做到这一点,以便仔细检查表单数据并仍然能够使用分页。

那是我的代码:

表类 Search\Model\CourseTable

class CourseTable {

    ...

    // without pagination
    // public function findAllByCriteria(CourseSearchInput $input) {
    // with pagination
    public function findAllByCriteria(CourseSearchInput $input, $pageNumber) {
        ...
        $select = new Select();
        $where = new Where();
        $having = new Having();
        ...
        // without pagination
        // $resultSet = $this->tableGateway->selectWith($select);
        // return $resultSet;
        // with pagination
        $adapter = new \MyNamespqce\Paginator\Adapter\DbSelect($select, $this->tableGateway->getAdapter());
        $paginator = new \Zend\Paginator\Paginator($adapter);
        $paginator->setCurrentPageNumber($pageNumber);
        return $paginator;
    }

    ... 

}

搜索\控制器\搜索控制器

class SearchController extends AbstractActionController {

    public function searchCoursesAction() {
        $form = $this->getServiceLocator()->get('Search\Form\CourseSearchForm');
        $request = $this->getRequest();
        if ($request->isPost()) {
            $courseSearchInput = new CourseSearchInput();
            $form->setInputFilter($courseSearchInput->getInputFilter());
            $form->setData($request->getPost());
            if ($form->isValid()) {
                $courseSearchInput->exchangeArray($form->getData());
                // without pagination
                // $courses = $this->getCourseTable()->findAllByCriteria($courseSearchInput);
                // with pagination
                $page = $this->params()->fromRoute('page');
                $paginator = $this->getCourseTable()->findAllByCriteria($courseSearchInput, $page);
            } else {
                $paginator = null;
            }
        } else {
            $paginator = null;
        }
        return new ViewModel(array(
            'form' => $form,
            // without pagination
            // 'courses' => $courses,
            // with pagination
            'paginator' => $paginator,
            'cities' => ...
        ));
    }

    ...

}

如何让它工作?

4

2 回答 2

1

我也有同样的问题,我已经解决了。但这不是好办法。可能这个想法会对你有所帮助。

我解决了它如下:(搜索Zend教程专辑模块的分页)

我在名为“search”和“index”的控制器中构建了两个动作。

每当提交搜索表单时,它总是将值发布到搜索操作。搜索操作使用搜索参数构建 url,并重定向到索引以显示搜索结果。

当点击分页链接时,发布的值会通过 url 传递。因此,每当索引操作要求搜索参数时,它总是以相同格式获取值。

我将路线定义如下:

'album' => array(
    'type'    => 'segment',
    'options' => array(
        'route'    => '/album[/:action][/:id][/page/:page][/order_by/:order_by][/:order][/search_by/:search_by]',
        'constraints' => array(
            'action'    => '(?!\bpage\b)(?!\border_by\b)(?!\bsearch_by\b)[a-zA-Z][a-zA-Z0-9_-]*',
            'id'     => '[0-9]+',
            'page' => '[0-9]+',
            'order_by' => '[a-zA-Z][a-zA-Z0-9_-]*',
            'order' => 'ASC|DESC',
        ),
        'defaults' => array(
            'controller' => 'Album\Controller\Album',
            'action'     => 'index',
        ),
    ),
),

有一个名为“search_by”的参数,它将所有搜索参数保存为 json 字符串。这就是重点,我知道这不好,但还没有找到其他方法。

“搜索”操作将此字符串构建为 -

public function searchAction()
{

    $request = $this->getRequest();

    $url = 'index';

    if ($request->isPost()) {
        $formdata    = (array) $request->getPost();
        $search_data = array();
        foreach ($formdata as $key => $value) {
            if ($key != 'submit') {
                if (!empty($value)) {
                    $search_data[$key] = $value;
                }
            }
        }
        if (!empty($search_data)) {
            $search_by = json_encode($search_data);
            $url .= '/search_by/' . $search_by;
        }
    }
    $this->redirect()->toUrl($url);
}

然后下一个索引操作解码字符串,执行必要的操作,并将 json 字符串发送给查看。

public function indexAction() {
    $searchform = new AlbumSearchForm();
    $searchform->get('submit')->setValue('Search');

    $select = new Select();

    $order_by = $this->params()->fromRoute('order_by') ?
            $this->params()->fromRoute('order_by') : 'id';
    $order = $this->params()->fromRoute('order') ?
            $this->params()->fromRoute('order') : Select::ORDER_ASCENDING;
    $page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1;
    $select->order($order_by . ' ' . $order);
    $search_by = $this->params()->fromRoute('search_by') ?
            $this->params()->fromRoute('search_by') : '';


    $where    = new \Zend\Db\Sql\Where();
    $formdata = array();
    if (!empty($search_by)) {
        $formdata = (array) json_decode($search_by);
        if (!empty($formdata['artist'])) {
            $where->addPredicate(
                    new \Zend\Db\Sql\Predicate\Like('artist', '%' . $formdata['artist'] . '%')
            );
        }
        if (!empty($formdata['title'])) {
            $where->addPredicate(
                    new \Zend\Db\Sql\Predicate\Like('title', '%' . $formdata['title'] . '%')
            );
        }

    }
    if (!empty($where)) {
        $select->where($where);
    }


    $album = $this->getAlbumTable()->fetchAll($select);
    $totalRecord  = $album->count();
    $itemsPerPage = 2;

    $album->current();
    $paginator = new Paginator(new paginatorIterator($album));
    $paginator->setCurrentPageNumber($page)
            ->setItemCountPerPage($itemsPerPage)
            ->setPageRange(7);

    $searchform->setData($formdata);

    return new ViewModel(array(
        'search_by'  => $search_by,
        'order_by'   => $order_by,
        'order'      => $order,
        'page'       => $page,
        'paginator'  => $paginator,
        'pageAction' => 'album',
        'form'       => $searchform,
        'totalRecord' => $totalRecord
    ));


}

所有排序和分页 url 都包含该字符串。

如果您之前知道所有搜索参数,那么您可以在路由中定义它,并以相同的方式传递,无需 json 字符串。由于我必须构建一个通用搜索,因此我构建了一个字符串。

“专辑搜索”的源代码可在https://github.com/tahmina8765/zf2_search_with_pagination_example的 git hub 中找到。

现场演示:http: //zf2pagination.lifencolor.com/public/album

于 2013-05-27T18:29:45.800 回答
1

问题评论中的@Sam 和@automatix 都是正确的。我的建议(尽管我正在寻找一个更简单的替代方案)是构建一个分段路由,它涵盖了您可能需要的所有选项,并从标准表单 POST 请求开始。

然后,在验证请求后,将表单数据传递给 paginationControl 助手,如下所示:

$resultsView = new ViewModel(array(
  'paginator' => $paginator,
  'routeParams' => array_filter($form->getData())
));

然后,在您的视图模板中,在 paginationControl 视图助手中设置路由参数:

<?php echo $this->paginationControl($paginator, 'Sliding', 'paginator/default',
    array('routeParams' => $routeParams)
) ?>

我在这里使用了array_filter,因为它是一种非常简单的方法,可以从表单数据中删除任何为空、空等的元素。这样你就不会传递你不需要的额外数据。

于 2013-07-06T07:20:16.050 回答