重新排序CActiveDataProvider

时间:2012-04-27 10:56:08

标签: php sorting yii

我在Yii中寻找一种方法来重新排序CActiveDataProvider。

目前我正在使用数据提供程序来获取已排序和分页的数据。

然后我使用foreach循环调整特定字段的数据来循环它,现在我需要根据新的调整数据对其进行重新排序。

我无法使用afterFind对模型中的数据进行排序,因为我需要查询另一个数据库(MySQL)以计算出计算出的值,并且它似乎不喜欢处理过程中的切换。

我不想使用CArrayDataProvider,因为除非我在调整数据时将控件放入循环中,否则没有明显的方法对返回的数据进行分页,但是我不知道有多少数据可以返回,说200条记录,但显示器的唯一调整20似乎违反直觉。

然后将所有内容推送到CGridView小部件。

所以现在我需要按升序重新调整下面的数组,例如。

$dataProvider = new CActiveDataProvider( blah );

foreach ( $dataProvider->getData() as $data ) {
 $data->Score += SomeModel::model()->findByPk(1)->NewScore;
}

array(
'Score' => 7
),
array(
'Score' => 6
)

$this->render('blah', array('data' => $dataProvider);

1 个答案:

答案 0 :(得分:2)

听起来你应该简单地实现一个包含现有CDataProvider的新CDataProvider。您将需要覆盖多个方法,但对于大多数方法,您只需转发到包装数据提供程序即可。代码可能最终看起来像这样:

$dataProvider = new CActiveDataProvider(...);
$myProvider = new CustomDataProvider($dataProvider);

// you could make CustomDataProvider work like this:
$myProvider->dataMutator = function(&$row, $key) {
    $row->Score = SomeModel::model()->findByPk(1)->NewScore;
};

$this->render('blah', array('data' => $myProvider);

CustomDataProvider::fetchData可能如下所示:

protected function fetchData()
{
    $data = $this->wrappedProvider->fetchData();
    array_walk(&$data, $this->dataMutator);
    uasort($data, function($a, $b) { return $a->Score - $b->Score; });
    return $data;
}

我在这里硬连线 - 这适用于原型设计,但是干净地指定后处理排序并非易事,因为:

  • CDataProvider公开了一个被忽略的sort属性。完全集成该属性要么是非平凡的工作(您必须编写遵循多个排序标准的代码等),要么更改CustomDataProvider.sort与其基类上的sort相比的语义。 CDataProvider已与CSort结婚,因此如果您想从OO角度寻求最干净的解决方案,最好从头开始实施IDataProvider
  • CustomDataProvider用户来说,如果单个'sort property is used, because sort`无法反映包装数据提供者将执行的操作以及“后处理”排序将会是什么,那么排序是如何工作的并不直观同时做;但是,上述两种情况都会影响最终结果。

我建议您使用原型,然后仔细考虑对象模型应该是什么。