2013-04-16 2 views
3

내 ZF2 응용 프로그램에 모듈 Search이 있습니다. 사용자는 검색 양식을 채우고 코스리스트를 얻습니다.Zend Framework 2에서 검색 모듈의 페이지 매김을 구현하는 방법은 무엇입니까?

이제 모듈에 페이지 매김을 추가하고 있습니다. paginator는 기본적으로 작동합니다. 페이지를 통해 데이터를 검색 할 수 있고 페이지 매김이 올바르게 표시됩니다 (페이지 당 10 개의 항목을 설정하는 dafault가있는 70 개의 검색된 코스에 대해 pagelinks 1-7).

하지만 여전히 유용하지 않습니다. 페이지 링크를 클릭하면 양식 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

예, 페이지 네비게이션 컨트롤의 뷰포트에 대한 네 번째 매개 변수는 $ params입니다.) https://github.com/zendframework/zf2/blob/master/library/Zend/View/Helper/PaginationControl.php#L85 i ASSUME (i don ' t KNOW)는 생성 된 링크에 첨부 될 쿼리 매개 변수입니다. – Sam

답변

1

나는 또한 동일한 문제가 있고, 나는 그것을 해결했다. 그러나 이것은 좋은 방법이 아닙니다. 아이디어가 도움이 될 수 있습니다. 나는이 개 "검색"라는 이름의 컨트롤러의 행동과 "인덱스"를 구축

(젠드 튜토리얼 앨범 모듈에 대한 검색 매김) :

나는 다음과 그것을 해결.

검색 양식이 제출 될 때마다 항상 검색 작업에 값을 게시합니다. 검색 작업은 검색 매개 변수로 URL을 작성하고 색인으로 리디렉션하여 검색 결과를 표시합니다.

그리고 페이지 매김 링크를 클릭하면 게시 된 값이 url을 통해 전달됩니다. 따라서 인덱스 액션이 검색 매개 변수를 요청할 때마다 항상 동일한 형식으로 값을 가져옵니다. JSON 문자열로 모든 검색 매개 변수를 유지할 것 "search_by"라는 이름의 매개 변수가 있습니다

'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', 
     ), 
    ), 
), 

다음과 같이

나는 경로를 정의했다. 이것이 내가 알기에 좋지 않은 점이지만 아직 다른 방법을 찾지 못했다.

"검색"액션 빌드로이 문자열 -, 필요한 조치를 수행하며 볼 수있는 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); 
} 

그리고 다음 인덱스 액션 디코드 문자열.

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 요청으로 시작합니다.

:

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

그런 다음 뷰 템플릿에서 paginationControl보기 도우미에서 경로 매개 변수를 설정 요청의 유효성을 검사 한 후 다음과 같이

그런 다음 paginationControl 도우미로 양식 데이터를 전달

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

여기서는 array_filter를 null, empty 등의 양식 데이터에서 요소를 제거하는 정말 간단한 방법으로 사용했습니다. 그렇게하면 필요없는 추가 데이터를 전달하지 않습니다.

관련 문제