Разбивка на страницы CakePHP: как я могу сортировать по нескольким столбцам для достижения "липкой" функциональности?


Я вижу, что эта страница не может сортировать два столбца одновременно билет все еще открыт, что наводит меня на мысль, что то, что я пытаюсь сделать, невозможно без обходного пути. Так что я думаю, что я ищу обходной путь.

Я пытаюсь делать то, что делают многие доски объявлений: иметь функцию "sticky". Я хотел бы сделать так, чтобы независимо от того, по какой ссылке в заголовке таблицы пользователь нажимает для сортировки, поле моей модели "sticky" всегда сортировалось первым, а затем на какой бы столбец пользователь ни нажал. Я знаю, что вы можете установить $this->paginate['Model']['order'] на все, что хотите, чтобы вы могли взломать его, чтобы сначала поместить поле "sticky", а затем выбранный пользователем столбец. Проблема с этим методом заключается в том, что разбиение на страницы не ведет себя должным образом после того, как вы это сделаете. Ссылки в заголовке таблицы работают неправильно, и переключение страниц тоже работает неправильно. Есть ли какой-то другой обходной путь?

Author: RavatSinh Sisodiya, 2012-12-12

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;
}
 15
Author: Nick, 2013-01-19 02:33:20

Что вы можете сделать, так это закодировать это в действии. Просто создайте запрос, который вы хотите, когда в 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, и это хорошо работает.

 0
Author: Alvaro, 2012-12-12 16:30:49

Вы можете использовать настраиваемое поле для сортировки и обновления компонента разбиения на страницы.

Код контроллера

$заказ['Документ.ДАТА'] = '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;
}
 0
Author: Muzammil Hussain, 2013-04-16 10:50:35

Простая вставка 'Тип параметра' => 'строка запроса', Показать пример кода:

$this->paginate = array(
    'conditions' => $conditions,
    'order' => array(
        'Post.name' => 'ASC',
        'Post.created' => 'DESC',

    ),
    'paramType' => 'querystring',

);

$this->set('posts', $this->paginate('Post'));
 0
Author: Sergio, 2015-08-11 04:20:20