Cakephp和分页多个结果集

时间:2012-09-05 20:09:34

标签: pagination cakephp-2.0

我的分页工作正常,因为$ this-> paginate在一个动作中被调用一次,但它似乎不是对多个调用的非常好的支持。这是我要做的......

function admin_index() {

    $published = $this->pagination('Post', array('status'=>1));
    $unpublished = $this->pagination('Post', array('status'=>0));

    $this->set('published', $published);
    $this->set('unpublished', $unpublished);
}

我的观点的简化版本是:

<h1>Unpublished Posts</h1>
<?php echo $this->element('table', array('posts'=>$unpublished)); ?>
<h1>Published Posts</h1>
<?php echo $this->element('table', array('posts'=>$published)); ?>

简单,我可以重复使用相同的元素来显示不同类型的数据。除了jquery table sorter / hack到Cakephp之外,是否真的无法将这些表分别分页?

我知道我可以将所有数据都粘贴在一个表中,然后只使用排序来区分状态,但我想先检查一下是否遗漏了某些内容。

2 个答案:

答案 0 :(得分:2)

由于没有太多的活动,我继续前进并做了合理的事情并找到了解决方法。以下是我提出的建议:

控制器:

function index() {
    $active = $this->paginate('Post', array('Post.status'=>1));     
    $activePaging = $this->request->params['paging']['Post'];

    $inactive = $this->paginate('Post', array('Post.status'=>0));
    $inActivePaging = $this->request->params['paging']['Post'];

    $this->set('active', $active);
    $this->set('inactive', $inactive);

    $this->request->params['paging']['Active'] = $activePaging;
    $this->request->params['paging']['InActive'] = $inActivePaging;
    unset($this->request->params['paging']['Post']);
}

public function paginate() {
    if ($this->request->is('ajax')) {
        $model = $this->request->params['named']['model'];
        $status = $model === 'Active' ? 1 : 0;

        $posts = $this->paginate('Post', array('Post.status'=>$status));
        $paging = $this->request->params['paging']['Post'];
        unset($this->request->params['paging']['Post']);
        $this->request->params['paging'][$model] = $paging;

        $this->set('posts', $posts);
        $this->set('model', $model);
        $this->render('/Posts/ajax_posts_paginated', 'ajax');
    }
}

观点:(简化)

index.ctp

<h3>Inactive Posts</h3>
<div class="well" id="InActive">
<?php echo $this->element('posts_table_paginated', array('posts'=>$inactive, 'model'=>'InActive')); ?>
</div>

<h3>Active Posts</h3>
<div class="well" id="Active">
<?php echo $this->element('posts_table_paginated', array('posts'=>$active, 'model'=>'Active')); ?>
</div>

元素/ posts_table_paginated.ctp

<?php
$this->Paginator->options(array(
    'update' => '#'.$model,
    'evalScripts' => true,
    'url'=> array('controller'=>'posts', 'action'=>'paginate', 'model'=>$model)
));
?>
<table>
    <tr>
        <th><?php echo $this->Paginator->sort('id', 'ID', array('model'=>$model)); ?></th>
        <th><?php echo $this->Paginator->sort('title', 'Title', array('model'=>$model)); ?></th>
        <th><?php echo $this->Paginator->sort('created', 'Created', array('model'=>$model)); ?></th>
        <th>Created by</th>
    </tr>
    <?php 
    foreach ($posts as $post): 
    ?>
    <tr>
        <td><?php echo $post['Post']['id']; ?></td>
        <td><?php echo $post['Post']['title']; ?></td>
        <td><?php echo $post['Post']['created']; ?></td>
        <td><?php echo $post['User']['username']; ?></td>
    </tr>
    <?php 
    endforeach; 
    ?>
</table>
<?php
    if ($this->params['paging'][$model]['count'] > 0) {
?>
<div id="pagination">
    <ul id="paginate">
        <?php
            echo $this->Paginator->prev(__('previous'), array('tag' => 'li', 'model'=>$model), null, array('tag'=>'li', 'class'=>'prev off'));
            echo $this->Paginator->numbers(array('tag'=>'li', 'model'=>$model, 'separator' => false));
            echo $this->Paginator->next(__('next'), array('tag' => 'li', 'model'=>$model), null, array('tag'=>'li', 'class'=>'next off'));
        ?>
    </ul>
</div>

<?php 
    }
    echo $this->Js->writeBuffer(); 
?>

答案 1 :(得分:0)

我遇到了同样的问题并解决了 cakephp版本2.5.3中以下类的问题 我没有检查我的方法是否也适用于旧版本。 首先,我创建了一个Helper和Component类,它扩展了PaginationComponent和PaginationHelper并覆盖了一些方法。

<强> /app/Controller/Component/_PaginatorComponent.php

<?php
/**
 * Filename:    _PaginatorComponent.php
 * User:        Mitja Stelzner
 * Date:        18.01.14
 */
App::import('Component', 'Paginator');
class _PaginatorComponent extends PaginatorComponent{
    public function paginate($object = null, $scope = array(), $whitelist = array())
    {
        //Adopt from the beginning of parent::paginate
        if (is_array($object))
            $object = null;
        $object = $this->_getObject($object);

        $options = $this->mergeOptions($object->alias); //get options
        $params = $this->Controller->request->params; //get params

        //if custom page name is set
        if(isset($params['named'][$options['pageRequestName']]))
        {
            //get the page number and set it as 'page' in the request (for other methods in the Component)
            $page = $params['named'][$options['pageRequestName']];
            $this->Controller->request->params['named']['page'] =intval($page);
        }
        else
            $this->Controller->request->params['named']['page'] = 1; //else set the page number to 1

        $pageRequestName = null; //important for parent::paginate

        $results = parent::paginate($object, $scope, $whitelist); // TODO: Change the autogenerated stub
        unset($this->Controller->request->params['named']['page']); //remove the appended page number

        //get the options again
        $options = $this->mergeOptions($object->alias);
        //and add the pageRequestName to the paging array
        if(isset($options['pageRequestName']))
        $this->Controller->request['paging'] = array_merge_recursive(
            (array)$this->Controller->request['paging'],
            array($object->alias => array('pageRequestName'=>$options['pageRequestName']))
        );
        return $results;
    }

}

<强> /app/View/Helper/_PaginatorHelper.php

<?php
/**
 * Filename:    _PaginatorHelper.php
 * User:        Mitja Stelzner
 * Date:        18.01.14
 */
App::uses('PaginatorHelper', 'View/Helper');
class _PaginatorHelper extends PaginatorHelper{
    public function link($title, $url = array(), $options = array()) {
        //change the page parameter 'page' to the custom pageRequestName
        if(isset($url['page']))
        {
            $params = $this->params($this->model);
            if(isset($params['pageRequestName']))
            {
                $url[$params['pageRequestName']] = $url['page'];
                unset($url['page']);
            }
        }
        return parent::link($title,$url,$options);
    }

    protected function _pagingLink($which, $title = null, $options = array(), $disabledTitle = null, $disabledOptions = array())
    {
        //Prevent the deletion of the variable model
        $disabledOptions['model'] = $options['model'];
        return parent::_pagingLink($which, $title, $options, $disabledTitle, $disabledOptions); // TODO: Change the autogenerated stub
    }

    private $model = null;
    public function numbers($options = array())
    {
        //Only to set the model again
        if(isset($options['model']))
            $this->model = $options['model'];
        return parent::numbers($options); // TODO: Change the autogenerated stub
    }


}

快速使用分页的视图元素:

<强> /app/View/Element/paging.ctp

<div class="paging">
    <?php
    $options = !isset($modelName)?array():array('model'=>$modelName);
    echo $this->Paginator->prev('< ' . __('zurück'), $options, null, array('class' => 'prev disabled'));
    echo $this->Paginator->numbers(array('separator' => '')+$options);
    echo $this->Paginator->next(__('vor') . ' >', $options, null, array('class' => 'next disabled'));
    ?>
</div>

您可以在视图中调用paging元素,如下所示: (Documentation

<?php
echo $this->element('paging',array('modelName'=>'Customer'));
?>

如果你想使用新创建的paginator,你必须说cakephp来使用你的类而不是普通的paginator。在您的控制器中,您可以像这样设置PaginatorHelper和PaginatorComponent: (找到here

public $helpers = array('Paginator' => array('className' => '_Paginator' ));
public $components = array('Paginator' => array('className' => '_Paginator' ));

控制器内部的使用情况。 $ paginate必须分组到Modelgroups中: (Documentation

public $paginate = array(
        'Customer' => array (
            'limit' => 25,
            'pageRequestName' => 'cpage'
        ),
        'Employer' => array (
            'limit' => 25,
            'pageRequestName' => 'erpage'
        ),
        'Employee' => array (
            'limit' => 25,
            'pageRequestName' => 'eepage'
        )
    );

但我在以下背景中使用它:

$this->Paginator->settings['Customer'] = array(
            'conditions'=>array(
                'OR'=>array(
                    array('name LIKE'=>'%'.$search_query.'%'),
                )
            ),
            'limit' => 5,
            'pageRequestName' => 'cpage'
        );
        $result = $this->Paginator->paginate('Customer');

我希望我可以帮助一些不想要javascript hack的人,但是真的有可能在一边有几个Paginations。

目前您只能使用'paramType'=&gt; '命名为'

在我看来,PaginationComponent和PaginationHelper中的原始代码很难阅读,扩展和适应。