在 Symfony 中结合使用 Structures/DataGrid、sfSmartView、Propel
今天需要在 symfony 中使用 datagrid 型控件对一个分页+排序的表格进行展示。但是 sfDataGrid 写得实在是太糟糕了,没有找到其他的比较好的 plugin。
PEAR 中的 Structures/DataGrid 倒是不错。但是两个问题:无法和现在偶使用的 sfSmartyView 直接结合,因为在 $datagrid->fill($smarty); 的时候,symfony 还没有生成 view instance,除非直接获取生成的 HTML_TABLE 或者类似的结果,这样不利于 MVC 的分离和对具体样式的控制;二是现有的 datasource 无法和 symfony 使用的 propel 直接结合,如果采用检索全部结果再传递给 Structures/DataGrid 进行分页处理,那么效率非常低下。
于是自己写一个 datasource,并且使用了一点技巧解决和 sfSmartyView 结合的问题。
Structures_DataGrid_DataSource_Propel 类的定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | class Structures_DataGrid_DataSource_Propel extends Structures_DataGrid_DataSource { protected $criteria = null; protected $con = null; protected $object = null; function __construct($object, $criteria, $con = null) { parent::Structures_DataGrid_DataSource(); $this->object = new $object(); $this->criteria = $criteria; $this->con = $con; } function count() { //TODO: this is not a good way, due to MySQL Bug #21787 $this->criteria->setLimit(0); $this->criteria->setOffset(0); $result = $this->object->doCount($this->criteria); return $result; } function sort($sortSpec, $sortDir = 'ASC') { switch (strtolower($sortDir)) { case 'asc' : $this->criteria->addAscendingOrderByColumn($sortSpec); break; case 'desc' : $this->criteria->addDescendingOrderByColumn($sortSpec); break; default : return PEAR::raiseError("Sorting dir must be ASC or DESC!"); } return true; } function fetch($offset = 0, $len = null) { $c = $this->criteria; $c->setOffset($offset); if (! is_null($len)) { $c->setLimit($len); } $objects = $this->object->doSelect($c); $result = array (); foreach ($objects as $object) { $result[] = $object->toArray(BasePeer::TYPE_COLNAME); } return $result; } } |
action 中的代码段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public function execute() { // get data source $c = new Criteria(); $datasource = new Structures_DataGrid_DataSource_Propel('SysUiaAccountPeer', $c); // setup datagrid $datagrid = & new Structures_DataGrid(10); $datagrid->bindDataSource($datasource); $datagrid->setDefaultSort(array ( SysUiaAccountPeer::USERNAME=>"DESC" )); $datagrid->addColumn(new Structures_DataGrid_Column('用户名', SysUiaAccountPeer::USERNAME, SysUiaAccountPeer::USERNAME, array (), ' ', '')); // add more columns here // use a tip to get output using smarty $smarty = $datagrid->setRenderer('smarty'); // set pager params $pager = $smarty->smartyGetPaging(array ( 'prevImg'=>"上一页", 'nextImg'=>"下一页", 'separator'=>"|", 'delta'=>"5", 'clearIfVoid'=>true, 'spacesBeforeSeparator'=>"1", 'spacesAfterSeparator'=>"1", 'firstPageText'=>'第一页', 'lastPageText'=>'最后页' ), $smarty); $this->dg = $datagrid->getOutput(); $this->pager = $pager; return sfView::SUCCESS; } |
模板中的处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <table> <!-- Build header --> <tr> {section name=col loop=$dg.columnSet} <th{$dg.columnSet[col].attributes}><!-- Check if the column is sortable --> {if $dg.columnSet[col].link != ""} <a href="{$dg.columnSet[col].link}">{$dg.columnSet[col].label}</a> <!-- Show the current ordering with an arrow --> {if $dg.columnSet[col].name == $smarty.request.orderBy} {if $smarty.request.direction == "ASC"}↑{elseif $smarty.request.direction == "DESC"}↓{/if} {/if} {else} {$dg.columnSet[col].label} {/if}</th> {/section} </tr> <!-- Build body --> {section name=row loop=$dg.recordSet} <tr {if $smarty.section.row.iteration is even}bgcolor="#EEEEEE"{/if}> {section name=col loop=$dg.recordSet[row]} <td{$columnSet[col].attributes}>{$dg.recordSet[row][col]}</td> {/section} </tr> {/section} <tr> <td colspan="...">{$pager}</td> </tr> </table> |