2012-10-24 131 views
3

我正在使用CSqlDataProvider來構造CGridview我不能使用CActiveRecord,因爲結果集是巨大的,並引發內存錯誤。這些列需要可排序。我應該如何實現這一目標?Yii CGridview與CSqlDataProvider排序

示例SQL

$orders_query_raw = 'select o.order_id, o.customer_name, o.customer_email, o.customer_advertiser, o.payment_method, o.created, o.last_updated, o.currency, o.currency_value, o.status, o.blinking, s.name, ot.text order_total, o.customer_id, op.product_id, o.phonebooking 
from `order` o, `order_total` ot, `order_status` s , order_product op 
where o.order_id = op.order_id and o.status = s.order_status_id and ot.order_id = o.order_id and s.language_id = '1' and ot.class = 'ot_total' group by o.order_id' 

SQL數據提供程序

$dataProvider = new CSqlDataProvider($orders_query_raw, array(
     'totalItemCount'=>$count, // get from a count query 
     'pagination'=>array(
      'pageSize'=>50, 
     ), 
    )); 

和GridView

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider' => $dataProvider, 
    'id'=>'order-grid', 
    'columns' => array(
     array(
      'header'=>'Order ID', 
      'value'=>array($this, 'gridOrderId'), 
      'type'=>'raw', 
     ), 
     array(
      'header'=>Yii::t('order', 'Customers'), 
      'name'=>'customer.fullName', 
      'value'=>'CHtml::link($data[\'customer_name\'], \'mailto:\'.$data[\'customer_email\'])', 
      'type'=>'raw', 
     ), 
     array(
      'header'=>Yii::t('order', 'Order total'), 
      'value'=>'strip_tags($data[\'order_total\'])', 
      'type'=>'raw', 
      'htmlOptions'=>array(
       'style'=>'text-align:right;', 
      ), 
     ), 
     array(
      'header' => Yii::t('order', 'Date Purchased'), 
      'name' => 'created', 
     ), 
     array(
      'header'=> Yii::t('order', 'Last modify date'), 
      'value'=>array($this, 'gridLastModified'), 
     ), 
     array(
      'header' => Yii::t('order', 'Status changed by'), 
      'value' => array($this, 'gridLastModifiedUserFirstName'), 
     ), 
     array(
      'header' => Yii::t('provider', 'Provider\'s code'), 
      'value' => array($this, 'gridProviderCode'), 
      'type' => 'raw', 
      'htmlOptions'=>array(
       'class'=>'nobr', 
      ), 
     ), 
     array(
      'header' => Yii::t('order', 'Follow up'), 
      'value' => array($this, 'gridFollowUp'), 
      'type' => 'raw', 
     ), 
     array(
      'header' => Yii::t('order', 'Order status'), 
      'value' => '$data[\'name\']', 
     ), 
     array(
      'class'=>'CButtonColumn', 
      'template'=>'{update}', 
      'header'=>'Action', 
      'buttons'=>array(
       'update'=>array(
        'url'=>'Yii::app()->createUrl(\'order/update\', array(\'order_id\'=>$data[\'order_id\']))', 
       ), 
      ), 
     ), 
    ), 
)); 

感謝

回答

6

要啓用(通過點擊列的標題)在網格視圖與數據提供商爲CSqlDataProvider排序,你需要最低限度的兩件事情:

  1. 必須定義CSort對象爲數據提供者,與attributes that would be sortable
  2. 必須定義name of the column但只有在情況下您指定網格視圖的columns屬性,否則如果列屬性是空白,什麼屬性在CSort對象提到的將是排序。

也就是說,其他答案應該在sql很簡單的情況下工作,並且來自1個表,但在您的情況下,sql有點複雜,即數據來自多個表,解決方案將稍微改變。

在這種情況下,您必須考慮列名衝突(如果有)以及CSort的attributes陣列的正確規範。

例子:

$dataProvider=new CSqlDataProvider($sql, array(
    'totalItemCount'=>$count, 
    'sort'=>array(
     'attributes'=>array(
      'order_id, order_total' // csv of sortable column names 
     ) 
    ) 
)); 

然後在網格:

array(
    'header'=>Yii::t('order', 'Order total'), 
    'name'=>'order_total',// to make header clickable to sort 
    'value'=>'strip_tags($data[\'order_total\'])', 
    'type'=>'raw', 
    'htmlOptions'=>array(
     'style'=>'text-align:right;', 
    ), 
), 
任何表(與其他的答案)的

  • 沒有衝突列名

  • 列名衝突:

    1. 首先,在sql中給出所有衝突的名稱別名。
    2. 其次,在CSort對象指定這些別名作爲排序attributes

      'attributes'=>array(
          'some_alias, some_other_alias' 
      ) 
      
    3. 指定name爲列columns

      array(
          'header'=>'Foo', 
          'name'=>'some_alias', 
          'value'=>'$data[\'some_alias\']' // this is actually redundant in this 
          // case, because the name will itself pick up the value, and we don't 
          // need to specify value explicitly if we are not applying any function to it 
      ) 
      

注意通過url調用進行排序只能通過speci來啓用搜索排序對象,不需要使用name,除非你想要點擊排序標題

+1

非常感謝您的明確解釋。 – Gihan

+0

不客氣。 –

1

嘗試如下

$sort = new CSort(); 
    $sort->defaultOrder = 'order_id'; // for initial order 
    $sort->attributes = array(
     'created' 
    ); 
$dataProvider = new CSqlDataProvider($orders_query_raw, array(
    'totalItemCount'=>$count, // get from a count query 
    'pagination'=>array(
     'pageSize'=>50, 
    ), 
    'sort'=>$sort 
));