我有一个对象Object1
,它以一对多关系引用Object2
:一个Object1
对多个Object2
。
在我的Object1
视图中,我试图仅包括相关Object2
项的yii'grid'GridView
。除了Object1
数据之外。只是Object2
项目中的一个GridView
。
使用下面这样的代码,我相信我必须在控制器中设置$dataProvider
和$searchModel
,但我不确定如何将Yii::$app->request->queryParams
与$id
链接起来。
我的代码只返回所有Object2
项,而不管它们与Object1
的关系如何,这对我来说虽然很有意义,但不是我想要的。
我甚至不确定这是否是正确的做法。有人知道解决方案吗?提前谢谢。
/* 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。
为Object1
和Object2
项创建单独的常规GridView
小部件。
扩展Object1
GridView的ActionColumn
,并添加到相关项的链接。我已经在这里解释过了,但为了更好地理解,我也在这里包含了代码:
[
'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',
]
);
},
],
],
修改Object2Controller
的index
动作以接受附加参数(对象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,
]);
}
Object2Search
的search()
方法还应处理附加参数:
/**
* @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
的部分以获得更好的视图组织。