0

我开发了自己的 joomla 2.5 自定义组件,用于在前端显示数据表。它包含过滤、分页和排序。当通过分页导航时,它总是只显示前 20 个。有没有办法覆盖在函数上生成的查询限制获取列表查询()。

我的 populateState 方法是

protected function populateState($ordering = null, $direction = null) {
        // Initialise variables.
        $app = JFactory::getApplication();

        $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
        $filter_order = $this->getUserStateFromRequest($this->context . '.filter_order', 'filter_order');
        //$filter_order = JRequest::getCmd('filter_order');
        $filter_order_Dir = $this->getUserStateFromRequest($this->context . '.filter_order_Dir', 'filter_order_Dir');
        //$filter_order_Dir = JRequest::getCmd('filter_order_Dir');

        'filter_region', '');

        $this->setState('filter_order', $filter_order);
        $this->setState('filter_order_Dir', $filter_order_Dir);


        // List state information
        $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit'));
        $this->setState('list.limit', $limit);

        $limitstart = JRequest::getVar('limitstart', 0, '', 'int');
        $this->setState('list.start', $limitstart);

        parent::populateState();
    } 

构造方法是

    function __construct() {
            parent::__construct();


            //Get configuration
            $app = JFactory::getApplication();
            $config = JFactory::getConfig();

            // Get the pagination request variables
            $this->setState('limit', $app->getUserStateFromRequest('com_jointcm.limit', 'limit', $config->getValue('config.list_limit'), 'int'));
            $this->setState('limitstart', JRequest::getVar('limitstart', 0, '', 'int'));
    }

List query method is

protected function getListQuery() {
        // Create a new query object.
        $db = JFactory::getDBO();
        $query = $db->getQuery(true);
 //code goes here...
..............

return $query;
}
4

4 回答 4

1

InJModelListgetItems()默认方法使用getStart()which 反过来使用您的模型getQuery()来获取查询返回的项目数的计数,然后通过_getListCount($query)该方法调用特定的数据库适配器版本getNumRows())。该值用于计算中getStart(),如果您有一个大型复杂查询并且不需要使用花哨的getStart()实现,您可以在模型中覆盖它(即您的JModelList类版本)

例如,对于我们的前端组件模型,它$query返回了相当复杂的 ' getListQuery,在它们最基本的实现中,它们执行类似于此的操作:

public function getStart()
{
    return $this->getState('list.start');
}

如果您不覆盖它,则会getStart()调用默认的 JModelList,如下所示:

/**
 * Method to get the starting number of items for the data set.
 *
 * @return  integer  The starting number of items available in the data set.
 *
 * @since   11.1
 */
public function getStart()
{
    $store = $this->getStoreId('getstart');

    // Try to load the data from internal storage.
    if (isset($this->cache[$store]))
    {
        return $this->cache[$store];
    }

    $start = $this->getState('list.start');
    $limit = $this->getState('list.limit');
    $total = $this->getTotal();
    if ($start > $total - $limit)
    {
        $start = max(0, (int) (ceil($total / $limit) - 1) * $limit);
    }

    // Add the total to the internal cache.
    $this->cache[$store] = $start;

    return $this->cache[$store];
}

但是,这可能不是问题区域,它更有可能在您的populateState(). populateState()您调用结束时parent::populateState()(如果在开始时调用它不会覆盖您的方法的结果)。

您似乎在复制 parent::populateState() 所做的工作,这可能是多余的,查看JModelList's implementation 您会看到:

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('global.list.limit', 'limit', $app->getCfg('list_limit'), 'uint');
        $limit = $value;
        $this->setState('list.limit', $limit);

        $value = $app->getUserStateFromRequest($this->context . '.limitstart', 'limitstart', 0);
        $limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0);
        $this->setState('list.start', $limitstart);

        // Check if the ordering field is in the white list, otherwise use the incoming value.
        $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);
    }
}

parent::populateState()导致list.start设置为的最明显的条件0是第一行,它检查您的对象context值,可能是那里出了问题并且您的对象context值等于 false。(我在任何地方都看不到context定义......所以,它会尝试猜测/context为你建立一个价值__construct())。

但是,它也可能是 getUserSateFromRequest() 处理从您的请求返回的值的方式,很难用可用的代码来判断。

于 2013-09-12T00:19:19.480 回答
1

经过一番挖掘并查看 JModelList 类的源代码后,我意识到问题出在 \libraries\joomla\application\component\modellist.php 文件,方法名称 public function getItems(),第 115 行。

我把它改成

public function getItems()
    {
        // Get a storage key.
        $store = $this->getStoreId();

        // Try to load the data from internal storage.
        if (isset($this->cache[$store]))
        {
            return $this->cache[$store];
        }

        // Load the list items.
        $query = $this->_getListQuery();
        //$items = $this->_getList($query, $this->getStart(), $this->getState('list.limit'));
$items = $this->_getList($query, $this->getState('limitstart'), $this->getState('list.limit'));

        // Check for a database error.
        if ($this->_db->getErrorNum())
        {
            $this->setError($this->_db->getErrorMsg());
            return false;
        }

        // Add the items to the internal cache.
        $this->cache[$store] = $items;

        return $this->cache[$store];
    }

变化是

$items = $this->_getList($query, $this->getStart(), $this->getState('list.limit'));

$items = $this->_getList($query, $this->getState('limitstart'), $this->getState('list.limit'));

它工作正常。

于 2013-09-11T06:01:38.137 回答
0

您是否在组件选项中定义了 list_limit?如果没有,则在组件选项中添加一个新参数并将其命名为 list_limit。这将允许您在组件选项中将分页限制设置为您想要的任何内容。

于 2013-09-10T22:03:07.340 回答
0

您可以$query->limit('0,40');getListQuery()函数中添加这样的限制

于 2013-09-10T15:09:03.783 回答