Разбивка на страницы CakePHP: как я могу сортировать по нескольким столбцам для достижения "липкой" функциональности?
Я вижу, что эта страница не может сортировать два столбца одновременно билет все еще открыт, что наводит меня на мысль, что то, что я пытаюсь сделать, невозможно без обходного пути. Так что я думаю, что я ищу обходной путь.
Я пытаюсь делать то, что делают многие доски объявлений: иметь функцию "sticky
". Я хотел бы сделать так, чтобы независимо от того, по какой ссылке в заголовке таблицы пользователь нажимает для сортировки, поле моей модели "sticky
" всегда сортировалось первым, а затем на какой бы столбец пользователь ни нажал. Я знаю, что вы можете установить $this->paginate['Model']['order']
на все, что хотите, чтобы вы могли взломать его, чтобы сначала поместить поле "sticky
", а затем выбранный пользователем столбец. Проблема с этим методом заключается в том, что разбиение на страницы не ведет себя должным образом после того, как вы это сделаете. Ссылки в заголовке таблицы работают неправильно, и переключение страниц тоже работает неправильно. Есть ли какой-то другой обходной путь?
4 answers
Пользователь ten1 на IRC-канале CakePHP помог мне найти решение. Я сказал ему, что если он опубликует ответ здесь, то я отмечу его как правильный, но он сказал, что я должен сделать это сам, так как у него еще нет учетной записи переполнения стека.
Хитрость заключается в том, чтобы ввести поле "привязка" в параметр "порядок" запроса, используя метод обратного вызова модели "До поиска", например:
public function beforeFind($queryData) {
$sticky = array('Model.sticky' => 'DESC');
if (is_array($queryData['order'][0])) {
$queryData['order'][0] = $sticky + $queryData['order'][0];
}
else {
$queryData['order'][0] = $sticky;
}
return $queryData;
}
Что вы можете сделать, так это закодировать это в действии. Просто создайте запрос, который вы хотите, когда в URL-адресе существуют некоторые параметры. (параметры должны быть отправлены с помощью GET)
Например:
public function posts(){
$optional= array();
if(!empty($this->params->query['status'])){
if(strlower($this->params->query['status']=='des')){
$optional= array('Post.status DESC');
}
else if(strlower($this->params->query['status']=='asc')){
$optional= array('Post.status ASC');
}
}
if(!empty($this->params->query['department'])){
//same...
}
//order first by the sticky field and then by the optional parameters.
$order = array('Post.stickyField DESC') + $optional;
$this->paginate = array(
'conditions' => $conditions,
'order' => $order,
'paramType' => 'querystring',
);
$this->set('posts', $this->paginate('Post'));
}
Я использовал нечто подобное для фильтрации некоторых данных с помощью $conditions
вместо $order
, и это хорошо работает.
Вы можете использовать настраиваемое поле для сортировки и обновления компонента разбиения на страницы.
Код контроллера
$заказ['Документ.ДАТА'] = 'asc';
$this->paginate = array(
"conditions"=> $conditions ,
"order" => $order ,
"limit" => 10,
**"sortcustom" => array('field' =>'Document.DATE' , 'direction' =>'desc'),**
);
Изменения в компоненте разбиения на страницы.
Публичная функция validateSort($объект, $параметры, $белый список = массив()) {
if (isset($options['sort'])) {
$direction = null;
if (isset($options['direction'])) {
$direction = strtolower($options['direction']);
}
if ($direction != 'asc' && $direction != 'desc') {
$direction = 'asc';
}
$options['order'] = array($options['sort'] => $direction);
}
if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
$field = key($options['order']);
if (!in_array($field, $whitelist)) {
$options['order'] = null;
}
}
if (!empty($options['order']) && is_array($options['order'])) {
$order = array();
foreach ($options['order'] as $key => $value) {
$field = $key;
$alias = $object->alias;
if (strpos($key, '.') !== false) {
list($alias, $field) = explode('.', $key);
}
if ($object->hasField($field)) {
$order[$alias . '.' . $field] = $value;
} elseif ($object->hasField($key, true)) {
$order[$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
$order[$alias . '.' . $field] = $value;
}
}
**if(count($options['sortcustom']) > 0 )
{
$order[$options['sortcustom']['field']] = $options['sortcustom']['direction'];
}**
$options['order'] = $order;
}
return $options;
}
Простая вставка 'Тип параметра' => 'строка запроса', Показать пример кода:
$this->paginate = array(
'conditions' => $conditions,
'order' => array(
'Post.name' => 'ASC',
'Post.created' => 'DESC',
),
'paramType' => 'querystring',
);
$this->set('posts', $this->paginate('Post'));