1

我正在寻找一种在 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);
4

1 回答 1

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比较的语义。与 结婚,因此如果您想从 OO 角度寻求最干净的解决方案,最好从头开始实施。sortCDataProviderCSortIDataProvider
  • CustomDataProvider如果单个“排序排序”property is used, because不能同时反映包装数据提供者将执行的操作和“后处理”排序将执行的操作,那么用户对排序的工作方式并不直观;但是,以上两者都会影响最终结果。

我建议你让原型工作,然后好好想想对象模型应该是什么。

于 2012-04-27T11:08:31.560 回答