简体   繁体   English

是否可以在CakePHP的同一视图中对两个不同的模型进行分页和排序?

[英]Is it possible to page and sort two different models in the same view in CakePHP?

I want to do something very straight forward and simple. 我想做一些非常直接和简单的事情。 I want to have two different sets of paginated data on the same page. 我想在同一页面上有两组不同的分页数据。 The two different sets depend on different models. 两个不同的集合取决于不同的模型。 For discussion's sake we'll say they are Image and Item . 为了讨论,我们会说它们是ImageItem

I can set up two pagers for two models, and get the correct set of objects. 我可以为两个模型设置两个寻呼机,并获得正确的对象集。 I can get the correct pager links. 我可以获得正确的寻呼机链接。 But when it comes to actually following the links to the parameters, both pagers read the parameters and assume they apply to them. 但是当涉及到实际跟随参数的链接时,两个寻呼机都会读取参数并假设它们适用于它们。

It winds up looking something like this: 它结束了这样的事情:

   $this->paginate = array (
        'Item'=>array(
            'conditions'=>array('user_id'=>$id),
            'limit' => 6, 
            'order' => array(
                'Item.votes'=>'desc', 
                'Item.created'=>'desc'
            ),
            'contain'=>array(
                'User', 
                'ItemImage' => array (
                    'order'=>'ItemImage__imageVotes desc'
                )
            )
        ),
        'Image'=>array(
            'limit'=>6,
            'contain'=>array(
                'User',
                'ItemImage'=>array('Item'),
            ),
            'order'=>array(
                'Image.votes'=>'desc',
                'Image.views'=>'desc'
            ),
            'conditions'=>array(
                'Image.isItemImage'=>1,
                'Image.user_id'=>$id
            )
        )
    );
    $this->set('items', $this->paginate('Item'));   
    $this->set('images', $this->paginate('Image'));

That's in the controller. 那是在控制器中。 In the view I have sort links that look like this: 在视图中,我的排序链接看起来像这样:

<div class="control"><?php echo $this->Paginator->sort('Newest', 'Image.created', array('model'=>'Image')); ?></div>

However, that yields a link that looks like this: 但是,这会产生如下所示的链接:

http://localhost/profile/37/page:1/sort:Image.created/direction:asc

There's nothing in there to tell the paginator which model I intend to sort. 那里没有任何东西可以告诉分页器我打算排序哪个模型。 So when I click on the link it attempts to sort both models by Image.created . 因此,当我点击链接时,它会尝试按Image.created对两个模型进行排序。 The result is an error, because Item cannot be sorted by Image.created . 结果是错误,因为Item不能按Image.created排序。 Is there something I'm doing wrong? 有什么我做错了吗? Or is this something that isn't supported by CakePHP's paginator? 或者这是CakePHP的分页器不支持的东西?

You'll need to override the paginate method for the Model of the Controller of that page. 您需要覆盖该页面的Controller模型的paginate方法。

I did something similar, maybe this snippet will help: 我做了类似的事情,也许这个片段会有所帮助:

function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array())
{
    $pageParams = compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'group');
    $this->contain('ModuleType', 'NodeDescriptor');
    $pageItems = $this->find('all',$pageParams);
    $pagesOut = array();
    foreach($pageItems as $pageItem)
    {
        $status = $pageItem['SiteAdmin']['status_id'];
        $moduleInfo = null;
        $nodeTitle = $pageItem['NodeDescriptor']['title'];
        $published = $pageItem['NodeDescriptor']['published'];
        $pageitemID = $pageItem['SiteAdmin']['id'];
        $moduleId =  $pageItem['SiteAdmin']['module_id'];
        $contName =  $pageItem['ModuleType']['controller'];
        if($moduleId)
        {
            $thisModel = ClassRegistry::getObject($moduleType);
            $thisModel->contain();
            $moduleInfo = $thisModel->read(null,$moduleId);
            $moduleInfo = $moduleInfo[$moduleType];
        }
        $pagesOut[] = array(
            'status'=>$status,
            'node'=>$nodeTitle,
            'published'=>$published,
            'info'=>$moduleInfo,
            'module_id'=>$moduleId,
            'contName'=>$contName,
            'pageitem_id'=>$pageitemID);
    }
    return $pagesOut;
}

By doing it this way, you gain control over the parameters passed to paginate, so you can pass model specific data, control flags etc. 通过这种方式,您可以控制传递给paginate的参数,因此您可以传递特定于模型的数据,控制标志等。

The easiest solution would be to implement both grids as elements that fetch their own data and use AJAX to load the elements into the page. 最简单的解决方案是将两个网格实现为获取自己的数据并使用AJAX将元素加载到页面中的元素。

The only other option would be to modify the params so you pass the params for both grids to each grid when sorting or stepping through pages. 唯一的另一种选择是修改参数,以便在排序或单步执行页面时将两个网格的参数传递给每个网格。 The code posted by Leo above is a good start. 上面Leo发布的代码是一个好的开始。 You can prepend the Model key from the paginate array onto each named param and make sure you pass all url params to the paginate function and you should be headed in the right direction. 您可以将模板键从paginate数组添加到每个命名的param上,并确保将所有url params传递给paginate函数,并且您应该朝着正确的方向前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM