É possível para a página de classificação e de dois modelos diferentes no mesmo ponto de vista no CakePHP?
-
25-09-2019 - |
Pergunta
Eu quero fazer algo muito simples e direto.Eu quero ter dois conjuntos diferentes de dados paginados na mesma página.Os dois conjuntos diferentes dependem de diferentes modelos.Para a discussão da causa vamos dizer que eles são Image
e Item
.
Eu posso configurar dois pagers para os dois modelos, e obtenha o conjunto correto de objetos.Eu posso obter o correto pager links.Mas quando se trata, na verdade, seguindo os links para os parâmetros, tanto pagers ler os parâmetros e assumir que eles se aplicam a eles.
Ventos acima de olhar algo como isto:
$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'));
Que está no controlador.No vista eu tenho uma espécie de links que esta aparência:
<div class="control"><?php echo $this->Paginator->sort('Newest', 'Image.created', array('model'=>'Image')); ?></div>
No entanto, o que produz um link parecido com este:
http://localhost/profile/37/page:1/sort:Image.created/direction:asc
Não há nada lá para dizer o paginator que o modelo que eu pretendo classificar.Então, quando eu clico no link ele tenta classificar ambos os modelos por Image.created
.O resultado é um erro, porque Item
não pode ser ordenado por Image.created
.Existe algo que eu estou fazendo de errado?Ou isso é algo que não é suportado pelo CakePHP do paginator?
Solução
A solução mais fácil seria implementar ambas as grades como elementos que buscam seus próprios dados e usam o Ajax para carregar os elementos na página.
A única outra opção seria modificar os parâmetros para que você passe os parâmetros para ambas as grades para cada grade ao classificar ou passar pelas páginas. O código publicado por Leo acima é um bom começo. Você pode prender a chave do modelo da matriz paginate em cada param nomeado e certificar -se de passar todos os parâmetros de URL para a função paginate e você deve estar indo na direção certa.
Outras dicas
Você precisará substituir o método paginate para o Modelo do Controlador da página.
Eu fiz algo semelhante, talvez este trecho irá ajudar:
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;
}
Por fazê-lo desta forma, você ganha controle sobre os parâmetros passados para o método paginate, assim você pode passar o modelo de dados específico, sinalizadores de controle etc.