首页 > 解决方案 > 直接使用分页器是无法识别配置的

问题描述

CakePHP 版本:4.0.1

介绍

我有两种方法都使用索引视图、索引搜索。在索引上,可以从选择列表中选择列,并且可以通过输入表单控件输入值,从而可以按列和值进行搜索。该数据通过 GET 发送到搜索方法,在该方法中检查空值并执行查询并呈现索引视图。

在具有以下配置的后来的 3x 版本中,索引视图对所选列进行了排序,这就是它的目的。

IE:索引视图在初始加载时对到期日期进行了排序,我选择了任务名称,然后将表单提交给搜索方法。task_name 在呈现视图时具有排序。


任务控制器

公共分页属性:

public $paginate = [
    'sortWhitelist' => [
       'Tasks.due_date',
       'Tasks.task_name',
       'Tasks.type',
       'Tasks.priority',
       'Tasks.related_to_name',
       'Contacts.first_name',
       'Contacts.last_name',
       'Accounts.account_name',
       'Tasks.task_desc'
    ]
];

搜索方法

我初始化从 index 方法接收的数据并将配置应用于分页属性并将查询对象发送到视图。

$this->setPage('');
$this->setSort($this->request->getQuery('column'));
$this->setDirection('asc');

// Validation of the page, sort, direction and limit is done here.
// IE: The $this->getSort() must be a string and not be numeric and has a strlen check
// and the $this->getDirection() can only be a string with values 'asc' or 'desc' etc. 

if (!empty($this->getPage())) {
    $this->paginate['page'] = $this->getPage();
}
$this->paginate['sort'] = $this->getSort();
$this->paginate['direction'] = $this->getDirection();
$this->paginate['limit'] = $this->getLimit();

debug($this->paginate);

$tasks = $this->paginate($query);
$this->set(compact('tasks'));

调试的结果是:

[
    'sortWhitelist' => [
        (int) 0 => 'Tasks.due_date',
        (int) 1 => 'Tasks.task_name',
        (int) 2 => 'Tasks.type',
        (int) 3 => 'Tasks.priority',
        (int) 4 => 'Tasks.related_to_name',
        (int) 5 => 'Contacts.first_name',
        (int) 6 => 'Contacts.last_name',
        (int) 7 => 'Accounts.account_name',
        (int) 8 => 'Tasks.task_desc'
    ],
    'sort' => 'Tasks.task_name',
    'direction' => 'asc',
    'limit' => (int) 25
 ]

结果
排序在 task_name 上。


几个月前,我升级到 4 并且刚刚修改了这个功能,发现排序是在索引上存在的列上,而不是在被选择的列上。我尝试了以下方法来解决问题:

我在食谱中引用了这些信息。这来自SO

$config = $this->paginate = [
    'page' => $this->getPage(),
    'sort' => $this->getSort(),
    'direction' => $this->getDirection(),
    'limit' => $this->getLimit()
];

debug($config);

$tasks = $this->Paginator->paginate($query, $config);

debug($this->Paginator);

$this->set(compact('tasks'));

调试 $config 的结果是:

[
    'page' => '',
    'sort' => 'Tasks.task_name',
    'direction' => 'asc',
    'limit' => (int) 25
]

调试 $this->Paginator 的结果是:

object(Cake\Controller\Component\PaginatorComponent) {

    'components' => [],
    'implementedEvents' => [],
    '_config' => [
        'page' => (int) 1,
        'limit' => (int) 20,
        'maxLimit' => (int) 100,
        'whitelist' => [
            (int) 0 => 'limit',
            (int) 1 => 'sort',
            (int) 2 => 'page',
            (int) 3 => 'direction'
        ]
    ]

}

注意:白名单包含限制、排序、页面和方向?限制是 20,我什至没有选择 20?

结果
排序在due_date,我需要在task_name 上排序。

额外信息
如果我然后单击 task_name 上的排序,则排序在 task_name 上。所有的工作都不能在初始负载上工作?


问题
如何配置分页属性,以便从搜索方法的初始加载开始对 task_name 进行排序。

谢谢Z。

标签: cakephp

解决方案


该修复程序有点昂贵且不理想,但确实有效。我对初始负载进行重定向。基本上提交表单进行搜索,然后重定向回搜索。IE:

if ($this->request->getQuery('initial') === 'yes') {

    $redirect = $this->request->getQuery('redirect', [
        'action' => 'search',
         '?' => [
             'method' => 'search',
             'column' => $this->getColumn(),
             'input' => $this->getInput(),
             'page' => $this->getPage(),
             'sort' => $this->getSort(),
             'direction' => $this->getDirection(),
             'limit' => $this->getLimit(),
             'filter' => $this->getFilter(),
         ]
    ]);

    return $this->redirect($redirect);
    exit(0);

}

$config = $this->paginate = [
    'sortWhitelist' => [
       'Tasks.due_date',
       'Tasks.task_name',
       'Tasks.type',
       'Tasks.priority',
       'Tasks.related_to_name',
       'Contacts.first_name',
       'Contacts.last_name',
       'Accounts.account_name',
       'Tasks.task_desc'
     ],
     'page' => $this->getPage(),
     'sort' => $this->getSort(),
     'direction' => $this->getDirection(),
     'limit' => $this->getLimit()
 ];

 $tasks = $this->Paginator->paginate($query, $config);
 $this->set(compact('tasks'));

排序现在在 task_name 上。

这消除了初始加载问题并在页面最初加载我知道排序工作后模拟使用。


推荐阅读