Yii - CGridView - 添加自定义属性

5
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$dataProvider,
    'columns'=>array(
        'title',          // display the 'title' attribute
        'category.name',  // display the 'name' attribute of the 'category' relation
        'content:html',   // display the 'content' attribute as purified HTML
        array(            // display 'create_time' using an expression
            'name'=>'create_time',
            'value'=>'date("M j, Y", $data->create_time)',
        ),
        array(            // display 'author.username' using an expression
            'name'=>'authorName',
            'value'=>'$data->author->username',
//HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
              'htmlOptions'=>array('class'=>'$data->author->username', 'secondAttribute' => $data->author->id),
//HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        ),
        array(            // display a column with "view", "update" and "delete" buttons
            'class'=>'CButtonColumn',
        ),
    ),
));

value选项中,我可以添加来自PHP的变量,但是对于htmlOptions选项则不行。为什么呢?
我怎样才能使用PHP变量创建属性?

3个回答

9
当您在columns集合中添加数组时,如果没有指定class属性,则创建的列的类型为CDataColumn。属性CDataColumn :: value已经明确记录

一个PHP表达式,将被评估每个数据单元格,其结果将呈现为数据单元格的内容。

因此,value具有特殊属性,即它会针对每一行进行eval操作,这就是为什么您可以"动态"设置它的原因。但这是一个例外,几乎没有其他东西支持相同的功能。

不过,你很幸运,因为属性 cssClassExpression 是另一个特殊例外,正好涵盖了这种用法。所以你可以像这样做:

array(
    'name'=>'authorName',
    'value'=>'$data->author->username',
    'cssClassExpression' => '$data->author->username',
),

编辑:我在从您的示例中复制/粘贴时犯了一个错误,并没有注意到您试图对htmlOptions内部的其他属性做同样的事情(我现在已删除代码的相关部分)。

如果您需要为动态值添加更多选项,则别无选择,只能子类化CDataColumn并覆盖renderDataCell方法(库存实现在这里)。


这个跟我的例子一样,但是它不起作用 - 没有人看到。 - Dirk Fograust
@DirkFograust:这明显与您的示例不同,请再仔细看一下。另外,请确保您正在使用最新版本的Yii。 - Jon
这只适用于cssClassExpression,但对于htmlOptions仍为NULL :( - Dirk Fograust
@DirkFograust:我只是错过了那个,抱歉。正如我所说,它可以工作的两种情况是例外,而不是规则。如果您需要它用于更多属性,则必须子类化CDataColumn - Jon
好的,什么也没有发生 :) 但是这仍然不起作用。我该怎么办?我有与股票实现相同的renderDataCell方法。 - Dirk Fograust
@DirkFograust:如果你有相同的方法,当然不会发生任何事情。看看它对cssClassExpression做了什么,然后做类似的事情。 - Jon

5

不知道这个方法是否仍适用(因为已经有一个被接受的答案),但是有一种稍微更好的解决方案,即使用“rowHtmlOptionsExpression”。这个选项指定了一个表达式,它将对每一行进行评估。如果eval()调用的结果是一个数组,那么它将被用作<tr>标记的htmlOptions。所以你现在可以基本上像这样使用它:

$this->widget('zii.widgets.grid.CGridView', array
(
   ...
   'rowHtmlOptionsExpression' => 'array("id" => $data->id)',
   ...

所有的标签都将有一个带有记录主键的id属性。只需稍微修改jQuery,从该标签获取id而不是额外列即可完成设置。


太好了...正是我想要的,但这语法也太奇怪了吧! - Developerium

2

扩展CDataColumn类

在protected/components/下创建名为DataColumn.php的文件,并按照以下内容进行编写:

/**
 * DataColumn class file.
 * Extends {@link CDataColumn}
 */
class DataColumn extends CDataColumn
{
    /**
     * @var boolean whether the htmlOptions values should be evaluated. 
     */
    public $evaluateHtmlOptions = false;

    /**
    * Renders a data cell.
    * @param integer $row the row number (zero-based)
    * Overrides the method 'renderDataCell()' of the abstract class CGridColumn
    */
    public function renderDataCell($row)
    {
        $data=$this->grid->dataProvider->data[$row];
        if($this->evaluateHtmlOptions) {
            foreach($this->htmlOptions as $key=>$value) {
                $options[$key] = $this->evaluateExpression($value,array('row'=>$row,'data'=>$data));
            }
        }
        else $options=$this->htmlOptions;
        if($this->cssClassExpression!==null)
        {
            $class=$this->evaluateExpression($this->cssClassExpression,array('row'=>$row,'data'=>$data));
            if(isset($options['class']))
                $options['class'].=' '.$class;
            else
                $options['class']=$class;
        }
        echo CHtml::openTag('td',$options);
        $this->renderDataCellContent($row,$data);
        echo '</td>';
    }
}

我们可以像这样使用这个新类:
$this->widget('zii.widgets.grid.CGridView', array(
    'id' => 'article-grid',
    'dataProvider' => $model->search(),
    'filter' => $model,
    'columns' => array(
        'id',
        'title',
        array(
            'name' => 'author',
            'value' => '$data->author->username'
        ),
        array(
            'class' => 'DataColumn',
            'name' => 'sortOrder',
            'evaluateHtmlOptions' => true,
            'htmlOptions' => array('id' => '"ordering_{$data->id}"'),
        ),
        array(
            'class' => 'CButtonColumn',
        ),
    ),
));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接