我开发了自己的joomla 2.5自定义组件,用于在前端显示数据表。它包含过滤,分页和排序。当通过分页导航时,它总是只显示前20个。 有没有办法覆盖在函数getListQuery()上生成的查询的限制。
我的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;
}
答案 0 :(得分:1)
在JModelList
的{{1}}中,默认方法使用getItems()
,后者又使用您的模型getStart()
来计算查询返回的项目数,通过getQuery()
进而调用_getListCount($query)
的特定数据库适配器版本。该值在getNumRows()
的计算中使用,如果您有一个大型复杂查询并且实际上不需要使用花哨的getStart()
实现,您可以在模型中覆盖它(即您的版本getStart()
类)
e.g。对于前端的组件模型,JModelList
返回了相当复杂的$query
,在最基本的实现中,他们做了类似的事情:
getListQuery
如果不覆盖它,则调用默认的JModelList public function getStart()
{
return $this->getState('list.start');
}
,如下所示:
getStart()
但是,这可能不是问题领域,更有可能在你的/**
* 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
导致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()
的{{1}}中最明显的条件是第一行,它会检查您的对象list.start
值,它可能是那里出了问题,你的对象0
值等于假。 (我无法在任何地方看到context
...因此,它会在context
中为您尝试猜测/构建context
值。< / p>
但是,它也可能是getUserSateFromRequest()处理请求返回的值的方式,很难用可用的代码来判断。
答案 1 :(得分:0)
您可以在$query->limit('0,40');
函数
getListQuery()
这样的限制
答案 2 :(得分:0)
您是否在组件选项中定义了list_limit?如果没有,则将新参数添加到组件选项并将其命名为list_limit。这样您就可以将分页限制设置为组件选项中的所需内容。
答案 3 :(得分:0)
经过一番挖掘并查看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'));
工作正常。