【问题标题】:Sort columns in joomla via populateState method通过 populateState 方法对 joomla 中的列进行排序
【发布时间】:2012-10-04 12:20:19
【问题描述】:

我在 Joomla 后端对表格列进行排序。我根据this tutorial调整设置。

我们可以看到建议覆盖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');

这个变量碰巧没有定义。

我错过了什么?我认为它以某种方式与正确的用户会话有关,但我没有任何证据。

【问题讨论】:

    标签: sorting joomla getstate


    【解决方案1】:

    在遇到同样的问题后,我发现,正如你所说,超类 populateState() 确实定义了行为。但是,它还会检查以确保您的字段在“白名单”中。

    if (!in_array($value, $this->filter_fields))
    

    如果您查看 com_content,您将在模型类的顶部看到此部分(在您的案例中为 models/articles.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 类知道“排序”字段在白名单中。显然,将字段替换为您希望过滤的字段。

    【讨论】:

    • 我没有对白名单部分给予足够的重视。感谢您指出!
    • 我也是!谢谢@moo2u2
    【解决方案2】:

    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 将从请求中获取变量。

    【讨论】:

    • 不应该这些$value = $app->getUserStateFromRequest($this->context.'.ordercol', 'filter_order', $ordering); ... $value = $app->getUserStateFromRequest($this->context.'.orderdirn', 'filter_order_Dir', $direction); 从状态变量中获取数据,尽管 $ordering 和 $direction 为空?
    猜你喜欢
    • 2019-09-07
    • 1970-01-01
    • 2020-02-03
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    相关资源
    最近更新 更多