Gridview Yii2:动态模型属性

Gridview Yii2:动态模型属性,gridview,dynamic,model,yii2,relation,Gridview,Dynamic,Model,Yii2,Relation,我有一张桌子: id | lang_name 表2:信息: id | message_code 表3:字典 id | message_id | lang_id | translation 我想把语言带到gridview。格式: 信息|代码|英译| | | | | | | | | | | |英译 由于语言的数量未知,我将数组中列的值传递给gridview 有一个问题:我需要将语言id的值传递给关系模型。我不知道怎么做 $searchModel = new langmess

我有一张桌子:

  id | lang_name
表2:信息:

  id | message_code
表3:字典

  id | message_id | lang_id | translation
我想把语言带到gridview。格式:

信息|代码|英译| | | | | | | | | | | |英译

由于语言的数量未知,我将数组中列的值传递给gridview

有一个问题:我需要将语言id的值传递给关系模型。我不知道怎么做

    $searchModel = new langmessages_search();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);



    $columns=array();       
    $columns[]=array('label'=>'message_code','attribute'=>'message_code');      
    $languages=Lang::find()->all();
    foreach($languages as $language){       
        $columns[]=array('label'=>$language->name,'attribute'=>'text');
        //'attribute'=>'text' ---> need to dynamically create the attribute or pass lang_id
    }

我希望您能提供帮助。

您的搜索模型可能如下所示:

class LangMessagesSearch extends Model
{

    public $id;
    public $messageCode;

    private $languages = [];


    public function __get($name)
    {
        if (isset($this->languages[$name])) {
            return $this->languages[$name];
        }

        return null;
    }

    public function __set($name, $value)
    {
        return $this->languages[$name] = $value;
    }

    public function getLanguageAttributes()
    {
        $languagesList = Lang::find()->all();

        $attributes = [];
        foreach ($languagesList as $lang) {
            $attributes[] = [
                'attribute' => $lang,
                'format' => 'raw',
                'headerOptions' => [
                    'title' => $lang,
                ],
                'content' => function($model, $key, $index) use ($lang) {
                    // you can do here something with $lang if you need so
                    $content = $model->{$lang};
                    return $content;
                }
            ];
        }

        return $attributes;
    }

    public function search($params)
    {
        // assume that getRecords() implemented here
        $records = $this->getRecords($params);


        $allModels = [];
        foreach ($records as $k => $v) {
            $model = new self;
            $model->id  = $records->id;
            $model->messageCode = $records->messageCode;

            $allModels[] = $model;
        }

        return $this->wrapIntoDataProvider($allModels);
    }

    private function wrapIntoDataProvider($data)
    {
        $provider = new \app\components\ArrayDataProvider(
            [
                'allModels' => $data,
                'pagination' => [
                    'pageSize' => 30,
                ],
            ]
        );

        return $provider;
    }
}
// take just first model in the list
$_model = $dataProvider->allModels[0];

$attributes = array_merge(
    [['class' => 'yii\grid\SerialColumn']],
    [
        'id',
        'messageCode'
    ],
    $_model->getLanguageAttributes()
);

echo \yii\grid\GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => $attributes
]);
最后在视图中显示网格:

class LangMessagesSearch extends Model
{

    public $id;
    public $messageCode;

    private $languages = [];


    public function __get($name)
    {
        if (isset($this->languages[$name])) {
            return $this->languages[$name];
        }

        return null;
    }

    public function __set($name, $value)
    {
        return $this->languages[$name] = $value;
    }

    public function getLanguageAttributes()
    {
        $languagesList = Lang::find()->all();

        $attributes = [];
        foreach ($languagesList as $lang) {
            $attributes[] = [
                'attribute' => $lang,
                'format' => 'raw',
                'headerOptions' => [
                    'title' => $lang,
                ],
                'content' => function($model, $key, $index) use ($lang) {
                    // you can do here something with $lang if you need so
                    $content = $model->{$lang};
                    return $content;
                }
            ];
        }

        return $attributes;
    }

    public function search($params)
    {
        // assume that getRecords() implemented here
        $records = $this->getRecords($params);


        $allModels = [];
        foreach ($records as $k => $v) {
            $model = new self;
            $model->id  = $records->id;
            $model->messageCode = $records->messageCode;

            $allModels[] = $model;
        }

        return $this->wrapIntoDataProvider($allModels);
    }

    private function wrapIntoDataProvider($data)
    {
        $provider = new \app\components\ArrayDataProvider(
            [
                'allModels' => $data,
                'pagination' => [
                    'pageSize' => 30,
                ],
            ]
        );

        return $provider;
    }
}
// take just first model in the list
$_model = $dataProvider->allModels[0];

$attributes = array_merge(
    [['class' => 'yii\grid\SerialColumn']],
    [
        'id',
        'messageCode'
    ],
    $_model->getLanguageAttributes()
);

echo \yii\grid\GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => $attributes
]);
上面的示例显示了如何在DynamicModel的帮助下验证$name和$email。validateData()方法创建DynamicModel的实例,使用给定的数据(本例中为名称和电子邮件)定义属性,然后调用yii\base\Model::validate()

可以使用hasErrors()检查验证结果,就像使用普通模型一样。您还可以访问通过模型实例定义的动态属性,例如,$model->name和$model->email

或者,您可以使用以下更“经典”的语法来执行即席数据验证:

$model = new DynamicModel(compact('name', 'email'));
$model->addRule(['name', 'email'], 'string', ['max' => 128])
    ->addRule('email', 'email')
    ->validate();

您是否尝试过使用这个:,我也使用它,它看起来比您的解决方案简单得多。我在这里使用它:您找到解决方案了吗?我也有同样的问题你的问题和这个一样吗?