【问题标题】:Yii - CGridView - add own attributeYii - CGridView - 添加自己的属性
【发布时间】:2014-12-16 22:53:12
【问题描述】:
$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 变量创建属性?

【问题讨论】:

    标签: php yii


    【解决方案1】:

    当您在columns 集合中添加数组而不指定class 属性时,正在创建的列类型为CDataColumn。属性CDataColumn::valueexplicitly documented

    一个 PHP 表达式将针对每个数据单元进行评估 结果将呈现为数据单元格的内容。

    因此,value 有一个特殊的属性,它会为每一行获得eval'ed,这就是为什么你可以“动态地”设置它的原因。然而,这是一个例外,几乎没有其他东西支持相同的功能。

    但是,您很幸运,因为属性cssClassExpression 是另一个完全涵盖此用例的特殊例外。所以你可以这样做:

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

    编辑:我在复制/粘贴您的示例时犯了一个错误,并且没有注意到您正在尝试对 htmlOptions 中的其他属性执行相同的操作(我现在已经删除了相关的部分代码)。

    如果您需要为动态值添加更多选项,您别无选择,只能继承 CDataColumn 并覆盖 renderDataCell 方法 (stock implementation is here)。

    【讨论】:

    • 这与我的示例相同。这不起作用 - 没有人显示。
    • @DirkFograust:这绝对与您的示例不一样。再看看。另外,请确保您使用的是最新版本的 Yii。
    • 这仅适用于 cssClassExpression,但对于 htmlOptions 这仍然是 NULL :(
    • @DirkFograust:我只是错过了,抱歉。正如我所说,它确实工作的两种情况是例外,而不是规则。如果你需要它来获得更多属性,你必须继承CDataColumn
    • 好的,什么都没有发生 :) 但这仍然不起作用。我怎样才能做到?我有与股票实施中相同的方法 renderDataCell。
    【解决方案2】:

    不知道这是否仍然适用(假设有一个公认的答案),但有一个更好的解决方案,形式为“rowHtmlOptionsExpression”。这指定了一个将为每一行计算的表达式。如果 eval() 调用的结果是一个数组,它将用作

    标记的 htmlOptions。所以你现在基本上可以使用这样的东西了:
    $this->widget('zii.widgets.grid.CGridView', array
    (
       ...
       'rowHtmlOptionsExpression' => 'array("id" => $data->id)',
       ...
    

    您的所有标签都将具有带有记录 PK 的 id 属性。 只需稍微修改 jQuery 以从该标签而不是额外的列中获取 id,您应该进行设置。

    【讨论】:

    • 太棒了...正是我想要的,但这是一个奇怪的语法人!
    【解决方案3】:

    扩展类 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',
            ),
        ),
    ));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-15
      • 2012-11-01
      相关资源
      最近更新 更多