Yii2:将$ model传递给外部函数

时间:2016-10-05 22:29:38

标签: gridview model yii2

我有几个Gridview,所有这些都有一些常见的列包含用于计数和求和数字的算法。为了集中维护这些列,我创建了一个我导入的外部类。它运作良好。

这是一个例子: gridview的:

        Column::percentPositive(),
        Column::countMinusOne(),
        Column::countZero(),
        Column::countPlusOne(),

列类:

    public static function countMinusOne()
{
    $x = [
        'attribute' => 'countMinusOne',
        'label' => '-1 ',
        'contentOptions' => ['class' => 'col-60 text-red'],
        'headerOptions' => ['class' => 'text-center text-red'],
    ];

    return $x;
}

我的问题: 每个模型显然略有不同,对于某些列,我需要将特定的$ model参数传递给静态函数。我希望这会奏效:

Column::CountMinusOne($model->invalidated),

我可以这样使用:

public static function countMinusOne($invalidated)
{
    $x = [
        'attribute' => 'countMinusOne',
        'label' => function() use($invalidated){
             // do my stuff here
         },
        'contentOptions' => ['class' => 'col-60 text-red'],
        'headerOptions' => ['class' => 'text-center text-red'],
    ];

    return $x;
}

然而,即使我在GridView中,$ model也无法识别,我收到一个错误:“Undefined variable:model”。我可以确认$ model在传统的GridView列元素中是可用的,但不能传递给静态函数。

如何将$ model->无效传递给我的函数??

非常感谢

根据Bizley响应进行更新

这是我可以到达的地方:

类别:

namespace app\models\columns;    
class Column extends \yii\grid\DataColumn
    {

        public $type;
        public $name;

        public function init()
        {
            parent::init();

            // here you can set all attributes based on 'type'
            switch ($this->type) {
                case 'test':
                    $this->value = function(){ return "hello ".$this->name;};
                    break;

GridView的:

    [
        'class' => 'app\models\columns\Column',
        'type' => 'test',
        'name' => function($model){ return $model->name;}
    ],

我收到错误:类Closure的对象无法转换为字符串。

我觉得奇怪的是,在GridView中,$ model-> name将返回“world”但是当我将$ model-> name传递给类时,它是一个巨大的对象,我无法访问该名称。我期待“世界”作为字符串传递给类,但相反,有一个对象。

我想要做的就是将名字传递给班级,但似乎无法做到。

如果我转储了类中存在的对象,我可以在对象的深处看到名称:

   ...
   [1] => app\models\Sponsor Object
     (
      ...
     [_attributes:yii\db\BaseActiveRecord:private] => Array
         (
            [id] => 120
            [name] => World

1 个答案:

答案 0 :(得分:0)

最好的方法是使用自己的类扩展yii\grid\DataColumn类,并在GridView中使用它。

现在您可以将此小部件设置为:

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        // ...
        [
            'class' => \namespace\to\YourColumn::className(),
            // configuration for YourColumn
        ]
    ],
]) ?>

通过设置YourColumn属性并添加/覆盖其方法,您可以对数据执行任何操作。

对于动态值,您使用value属性,该属性可以是带签名的闭包:

function ($model, $key, $index, $column)

所以这里缺少$model

修改 :(更多详情)

示例:

列类:

namespace app\models\columns

class Column extends \yii\grid\DataColumn
{
    public $type;

    public function init()
    {
        parent::init();

        // here you can set all attributes based on 'type'
        switch ($this->type) {
            case 'percentPositive':
                // ...
                break;
            case 'countMinusOne':
                // parameters taken from question
                $this->attribute = 'countMinusOne';
                $this->label = '-1 ';
                $this->contentOptions = ['class' => 'col-60 text-red'];
                $this->headerOptions = ['class' => 'text-center text-red'];
                break;
            case 'countZero':
                // ...
                break;
            case 'countPlusOne':
                // ...
                break;
        }
    }
}

现在GridView:

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        // ...
        [
            'class' => 'app\models\columns\Column',
            'type' => 'countMinusOne',
            'value' => function ($model, $key, $index, $column) {
                // use the proper attribute you need
                // in Column class it's $this->value
                return $model->name;
            }
        ]
    ],
]) ?>