【问题标题】:Cakephp and paginating multiple result setsCakephp 和分页多个结果集
【发布时间】:2012-09-05 20:09:33
【问题描述】:

当 $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 / hacks to Cakephp之外,真的没有办法单独对这些表进行分页吗?

我知道我可以将所有数据放在一个表中,然后只使用排序来区分状态,但我想先检查我是否遗漏了什么。

【问题讨论】:

标签: pagination cakephp-2.0


【解决方案1】:

由于这方面的活动不多,我继续做合理的事情并想出了一个解决方法。以下是我想出的:

控制器:

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(); 
?>

【讨论】:

    【解决方案2】:

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

    /app/Controller/Component/_PaginatorComponent.php

    <?php
    /**
     * Filename:    _PaginatorComponent.php
     * User:        
     * 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:        
     * 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>
    

    您可以像这样在视图中调用分页元素: (Documentation)

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

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

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

    控制器内部的用法。 $paginate 必须被分组到模型组中: (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 的人,但确实有可能在一侧有多个分页。

    目前你只能使用 'paramType' => 'named'

    在我看来,PaginationComponent 和 PaginationHelper 中的原始代码难以阅读、扩展和改编。

    【讨论】:

      猜你喜欢
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 2010-11-24
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多