Сортировка столбцов в joomla - метод populateState
Я сортирую столбцы таблицы в Joomla Backend. Я настраиваю настройки в соответствии с этим уроком.
Как мы видим, предлагается переопределить populateState
метод и вручную получить параметры сортировки.
public function populateState() {
$filter_order = JRequest::getCmd('filter_order');
$filter_order_Dir = JRequest::getCmd('filter_order_Dir');
$this->setState('filter_order', $filter_order);
$this->setState('filter_order_Dir', $filter_order_Dir);
}
Но я заметил, что родной компонент com_content
не устанавливает эти параметры явно в файле модели administrator/components/com_content/models/articles.php
,
protected function populateState($ordering = null, $direction = null)
{
// Initialise variables.
$app = JFactory::getApplication();
$session = JFactory::getSession();
............................................
............................................
............................................
// List state information.
parent::populateState('a.title', 'asc');
}
Вместо этого он просто вызывает родителя populateState
, И на самом деле JModelList::populateState()
включает в себя это:
protected function populateState($ordering = null, $direction = null)
{
// If the context is set, assume that stateful lists are used.
if ($this->context) {
$app = JFactory::getApplication();
.....................................
.....................................
.....................................
$value = $app->getUserStateFromRequest($this->context.'.ordercol', 'filter_order', $ordering);
if (!in_array($value, $this->filter_fields)) {
$value = $ordering;
$app->setUserState($this->context.'.ordercol', $value);
}
$this->setState('list.ordering', $value);
// Check if the ordering direction is valid, otherwise use the incoming value.
$value = $app->getUserStateFromRequest($this->context.'.orderdirn', 'filter_order_Dir', $direction);
if (!in_array(strtoupper($value), array('ASC', 'DESC', ''))) {
$value = $direction;
$app->setUserState($this->context.'.orderdirn', $value);
}
$this->setState('list.direction', $value);
}
else {
$this->setState('list.start', 0);
$this->state->set('list.limit', 0);
}
}
Вот я и пытаюсь подражать коду родного com_content
, Таким образом, я предполагаю, что
class CompViewData extends JView
{
function display($tpl = null)
{
$this->state = $this->get('State');
вызовет родителя JModelList::populateState()
(поэтому я не переопределяю это в модальном классе) и установил $this->setState('list.ordering', $value);
, Но по какой-то причине, когда я призываю $this->state->get()
в getListQuery()
построить мой запрос SQL с упорядочением
protected function getListQuery()
{
$orderCol = $this->state->get('list.ordering', 'id');
$orderDirn = $this->state->get('list.direction', 'asc');
эти переменные не определены.
Что мне не хватает? Я предполагаю, что это как-то связано с правильным сеансом пользователя, но у меня нет никаких доказательств вообще. Помощь очень ценится.
2 ответа
Просто столкнувшись с той же проблемой, я обнаружил, что, как вы сказали, суперкласс populateState() действительно определил поведение. Однако он также проверяет, находится ли ваше поле в "белом списке".
if (!in_array($value, $this->filter_fields))
Если вы посмотрите на com_content, то увидите этот раздел в верхней части класса модели (в вашем случае models/article.php):
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'id', 'a.id',
'title', 'a.title',
//...(more fields here)
'publish_up', 'a.publish_up',
'publish_down', 'a.publish_down',
);
$app = JFactory::getApplication();
$assoc = isset($app->item_associations) ? $app->item_associations : 0;
if ($assoc)
{
$config['filter_fields'][] = 'association';
}
}
parent::__construct($config);
}
Вам нужно будет включить этот раздел, чтобы класс ModelList знал, что поле 'ordering' находится в белом списке. Очевидно, замените поля теми, по которым вы хотите фильтровать.
Joomla JModelList
определяет populateState
как это
protected function populateState($ordering = null, $direction = null)
Это означает, что если у вас нет populateState
переопределить в вашем классе, это будет вызвано, но не получит значений. Минимальное требование - установить значения по умолчанию, если вы хотите использовать порядок. Вы можете полностью удалить этот метод из своего класса, если вы вообще не планируете использовать порядок.
Итак, минимум, что вам нужно, это интерполировать в своем классе
protected function populateState($ordering = null, $direction = null) {
parent::populateState('id', 'ACS');
}
В противном случае вы ничего не получите в $state->get()
или же $this->state->get()
если вы не нажмете на столбец заказа. Потом родительский populateState
возьмет переменные из запроса.