我正在使用Yii的Dataprovider根据“点”列输出一堆用户;
它现在运作正常,但我必须添加一个功能,所以如果用户在线,他会得到额外的300分。
杰克有100分,里士满有300分,但杰克在线,所以杰克的排名应该高于里士满。以下是我的解决方案:
$user=new Rank('search');
$user->unsetAttributes();
$user->category_id = $cid;
$dataProvider = $user->search();
$iterator = new CDataProviderIterator($dataProvider);
foreach($iterator as $data) {
//check if online ,update points
}
然而,这个CDataProviderIterator似乎直接将我的分页更改为最后一页,我甚至无法再切换页面。我该怎么办?
非常感谢!
这是listview:
$this->widget('zii.widgets.CListView', array(
'id'=>'userslist',
'dataProvider'=>$dataProvider,
'itemView'=>'_find',
'ajaxUpdate'=>false,
'template'=>'{items}<div class="clear"></div><div style="margin-right:10px;"><br /><br />{pager}</div>',
'pagerCssClass'=>'right',
'sortableAttributes'=>array(
// 'create_time'=>'Time',
),
));
更新了Rank.php模型中的代码
$criteria->with = array('user');
$criteria->select = '*, (IF(user.lastaction > CURRENT_TIMESTAMP() - 1800, points+300, points)) as real_points';
$criteria->order = 'real_points DESC';
然而,它引发了我的错误:
Active record "Rank" is trying to select an invalid column "(IF(user.lastaction > CURRENT_TIMESTAMP() - 1800". Note, the column must exist in the table or be an expression with alias.
答案 0 :(得分:1)
CDataProviderIterator迭代每个dataprovider值,并在结束时停止。我不知道这些类的所有内容,但认为原因在于某个内部迭代器,它在foreach之后停止在dataprovider的末尾。 当您不需要加载所有数据(对于大量数据)但需要处理每一行时,将使用迭代器。
要解决您的问题,只需在视图“_find”中处理数据。如果在线加点。
或者,如果您只想在模型中放置此逻辑(在MVC :)之后),请将方法添加到模型中:
public function getRealPoints() {
return ($this->online) ? ($this->points + 300) : $this->points;
}
您可以使用$user->realPoints
根据用户在线状态获取积分
更新:要按“realPoints”订购列表,您需要在SQL中获取它。 所以使用你的代码:
$user=new Rank('search');
$user->unsetAttributes();
$user->category_id = $cid;
$dataProvider = $user->search();
并修改$user->search()
功能,添加:
$criteria->select = '*, (IF(online='1', points+300, points)) as real_points';
$criteria->order = 'real_points DESC';
其中online
和points
- 您的表格列。