我正在对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);
.但是出于某种原因,当我在getListQuery()
中调用$this->state->get()
以使用排序构建我的SQL查询时
protected function getListQuery()
{
$orderCol = $this->state->get('list.ordering', 'id');
$orderDirn = $this->state->get('list.direction', 'asc');
此变量恰好未定义。
我错过了什么?我认为它与适当的用户会话有某种联系,但我没有任何证据。
在遇到同样的问题后,我发现,正如你所说,超类 populateState() 确实定义了行为。 但是,它也会进行检查以确保您的字段在"白名单"中。
if (!in_array($value, $this->filter_fields))
如果您查看com_content您将在模型类的顶部看到此部分(在您的案例中为模型/文章.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 类知道"排序"字段在白名单中。 显然,将字段替换为要过滤的字段。
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
将从请求中获取变量。