yii2使用相同型号的下拉列表过滤网格

时间:2017-04-20 17:03:14

标签: yii yii2 yii2-advanced-app yii2-model kartik-v

我在联系人模型中使用以下功能

public static function getParents()
{
    return $this->hasMany(Contact::className(), ['parent_id' => 'id']); 
}

我希望在我的视图的filter属性中返回此数组:

        [
        'attribute' => 'parent_id',
        'value' => function ($model) {
            return $model->parent ? $model->parent->name : null;
        },
        'hAlign' => 'left',
        'vAlign' => 'middle',
        //'filter' => ArrayHelper::map(Contact::find()->where(['<>', 'parent_id', 0])->orderBy('name')->asArray()->all(), 'id', 'name'),
        'filter' => ArrayHelper::map(Contact::parents()->asArray()->all(), 'id', 'name'),
        'filterWidgetOptions' => [
            'pluginOptions' => ['allowClear' => true],
        ],
        'filterInputOptions' => ['placeholder' => 'Parent'],
        'format' => 'raw'
    ],

但是我收到以下错误:调用未定义的方法common \ models \ Contact :: parents()

其余的关系工作正常,例如属性$ model-&gt; parent

我使用的是以下代码,但这是错误的,因为dosn在同一个表中带有parent_id的名称,但带有parent_id的记录名称

'filter' => ArrayHelper::map(Contact::find()->where(['<>', 'parent_id', 0])->orderBy('name')->asArray()->all(), 'id', 'name'),

我设法使用表单中的2个查询来修复我的过滤器,但不是很优雅:

$subQuery = Contact::find()->select('parent_id')->where(['<>', 'parent_id', 0]);
$parents = ArrayHelper::map(Contact::find()->where(['in', 'id', $subQuery])->orderBy('name')->asArray()->all(), 'id', 'name')

正确答案后更新

我把逻辑放在模块中以便在其他地方重用它并使用getParentsArray而不仅仅是parentsArray

public static function getParentsArray() {
    $subQuery = Contact::find()->select('parent_id')->where(['<>', 'parent_id', 0]);
    $parents = ArrayHelper::map(Contact::find()->where(['in', 'id', $subQuery])->orderBy('name')->asArray()->all(), 'id', 'name');
    return $parents;
}
在视图或控制器中

$parents = Contact::getParentsArray();

2 个答案:

答案 0 :(得分:1)

我认为你的问题是这个;您正在使用方法Contact::parents(),但您的模型中不存在此方法。您已声明方法getParents(),该方法允许Yii使用魔法getter方法访问parents Contact::parents

Yii如何使用这两个函数有一个微妙但重要的区别,这将影响您如何使用它们生成适合在您的下拉列表中使用的数组: 第一个,Contact::parents()使用您声明的关系来获取所有父记录。它返回一个类Contact的模型数组,正如您在方法中声明的那样。

第二种方法是直接调用静态方法getParents()。这样做的好处是它返回ActiveQuery的实例,然后允许您使用与asArray()关联的all()ActiveQuery方法。

因此,对于您的用例,我会在模型中添加一些代码来生成您的下拉列表。这样做的好处是它可以将模型逻辑(这是)保留在模型中,然后在其他情况下也可以重用。

因此,在您的模型中,创建此方法;

public static function getParentsArray(){
return ArrayHelper::map(self::getParents()->asArray()->all(), 'id', 'name');
}

然后您可以在视图文件中使用它,如此;

'filter' => Contact::parentsArray()

答案 1 :(得分:0)

Contact::parents()表达式正在调用静态方法parents(),该方法在您的代码中不存在。在这个上下文中,parents()不是关系。使用此表达式没有初始化QueryInterface。

对于您的任务,请使用$dataProvider作为基础来与父母联系。

'filter' => ArrayHelper::map($dataProvider->getModels()[0]->parents->find()->all(),'id','name'),

您可以在此处验证$dataProvider的大小,以进入第一级。