2013-04-16 91 views
3

我在我的ZF2應用程序中有一個模塊Search。用戶填寫搜索表單並獲取課程列表。如何在Zend Framework 2中爲搜索模塊實現分頁?

現在我將分頁添加到模塊中。分頁器基本上可以工作:我可以通過它檢索數據並且分頁顯示正確(頁面鏈接1-7用於70個找到的課程,其中每個頁面默認設置10個項目)。

但它仍然不可用。當我點擊頁面鏈接時,表單POST數據將丟失。我知道 - 它無法工作,我如何實現它(請參閱下面的代碼)。但我不知道,如何正確地做到這一點,以便檢查表單數據並能夠使用分頁。

這是我的代碼:

表類搜索\型號\ 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; 
    } 

    ... 

} 

搜索\控制器\ SearchController

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' => ... 
     )); 
    } 

    ... 

} 

如何得到它的工作?

+2

搜索結果和搜索頁面應該通過'$ _GET',因此GET-Params可以用於將來的分頁鏈接。這就是它的全部。 – Sam

+0

只要切換到'$ _GET',問題就不會解決。 「GET-Params」可以用於未來的分頁鏈接嗎?參數應該傳遞給視圖,然後傳遞給'PaginationControl'視圖助手? – automatix

+0

是的,paginationControl viewHelper的第四個參數是$ params;)https://github.com/zendframework/zf2/blob/master/library/Zend/View/Helper/PaginationControl.php#L85我假設(我不' t知道)這些查詢參數是附加到生成的鏈接。 – Sam

回答

1

我也有同樣的問題,我已經解決了。但這不是好的方法。可能是這個想法會幫助你。

我解決了這個問題如下:(搜索分頁爲Zend的教程專輯模塊)

我建立一個名爲「搜索」控制器兩項行動和「索引」。

每當提交搜索表單時,它總是會將值發送到搜索操作。搜索操作使用搜索參數構建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字符串的情況下以相同方式傳遞。由於我必須建立一個通用搜索,所以我構建了一個字符串。

git hub的https://github.com/tahmina8765/zf2_search_with_pagination_example提供「相冊搜索」的源代碼。

現場演示:http://zf2pagination.lifencolor.com/public/album

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,因爲它是一種非常簡單的方法,可以從表單數據中刪除空,空等任何元素。這樣你就不會傳遞你不需要的額外數據。