【问题标题】:Yii2: GridView for one-to-many relational dataYii2:用于一对多关系数据的 GridView
【发布时间】:2016-07-31 17:39:45
【问题描述】:

我有一个对象Object1,它以一对多的关系引用Object2:一个Object1 到多个Object2

在我的Object1 视图中,我试图仅包含相关Object2 项目的yii\grid\GridView。除了Object1 数据之外。仅GridView 中的Object2 项。

使用下面这样的代码,我相信我必须在我的控制器中同时设置$dataProvider$searchModel,但我不确定如何将Yii::$app->request->queryParams$id 链接起来。

我的代码只返回所有 Object2 项目,无论它们与 Object1 的关系如何,虽然这对我来说非常有意义,但不是我要寻找的。​​p>

我什至不确定这是不是正确的方法。有谁知道解决方案?提前致谢。

/* Object1 model */
public function getRelations() {
    return $this->hasMany(Object2::className(), ['relation' => 'id']);
}

/* Object1 view */
<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        'id',
        'attr1',
        'attr2',
        'attr3',
        'attr4',
        ['class' => 'yii\grid\ActionColumn'],
    ],
]);

/* Object1 controller */
public function actionView($id){
    $searchModel = new Object2Search();
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

    return $this->render('view', [
        'model' => $this->findModel($id),
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);
}

【问题讨论】:

  • 你想在你的gridview中显示什么?
  • Objectt2 的属性,其relation 属性是视图中当前正在查看的Object1id
  • object1 中的每个对象在object2 中都有多个对象。您可以获取关系并使用foreach 来显示它们
  • 是的。我当然可以。但我想使用 GridView。
  • 可以自定义gridview

标签: php yii2


【解决方案1】:

我可以建议替代方法,而不是在详细视图中呈现 GridView。

Object1Object2 项目创建单独的常规GridView 小部件。

扩展ActionColumn of Object1 GridView 并附加指向相关项目的链接。我已经解释过here,但我也在这里包含代码以便更好地理解:

[
    'class' => 'yii\grid\ActionColumn',
    'template' => '{objects2} {view} {update} {delete}',
    'buttons' => [
        'objects2' => function ($url, $model, $key) {
            /* @var $model common\models\Object1 */
            return Html::a(
                '<span class="glyphicon glyphicon-arrow-down"></span>',
                ['objects2/index', 'object1_id' => $model->id],
                [
                    'title' => 'Objects 2',
                    'aria-label' => 'Objects 2',
                    'data-pjax' => '0',
                ]
            );
        },        
    ],
],

修改Object2Controllerindex 操作以接受附加参数(对象1 id):

/**
 * @param integer $object1_id
 * @return string
 * @throws \yii\web\NotFoundHttpException
 */
public function actionIndex($object1_id)
{
    $searchModel = new Object2Search;
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);
}

Object2Searchsearch() 方法还应该处理附加参数:

/**
 * @param array $params
 * @return ActiveDataProvider
 */
public function search($params)
{
    $query = Object2::find()->where(['object1_id' => $params['object1_id']]);

    $dataProvider = new ActiveDataProvider([
        'query' => $query,            
    ]);

    if (!($this->load($params) && $this->validate())) {
        return $dataProvider;
    }

    // Additional filters

    return $dataProvider;
}

确保在rules() 和其他过滤器中不包含object1_id

至于Object2项目的显示,只需排除object1_id列即可。

显然这可以定制更多,这只是一个基本的例子。

这种方法的主要优点是不同类型模型的代码是分开的,更容易维护。

至于在详细视图中使用它,修改Object2Search模型的search()方法以通过object1_id应用初始过滤器,但在这种情况下,从查询参数中传递id参数(来自view 行动):

$query = Object2::find()->where(['object1_id' => $params['id']]);

GridView 使用部分内容以更好地组织视图。

【讨论】:

  • 这不能回答我的问题。
  • 感谢您的回答,但我是否正确,这将显示所有 Object1data,并在单击图标时显示相关数据?这不是我问的问题。
  • @MrGoobri 在解释此替代方案后阅读附加备注。您只需要按对象 1 id 应用初始过滤器。
  • 你是对的,你在底部提供的小代码 sn-p 确实适用于这个实例,是的,但随后它会破坏 Object2 索引视图,我看到所有 @987654346 @ 实例?
  • 我想我错了。对不起。你是对的。谢谢您的帮助。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多