Wiki
Gridview 如何对关联模型的数据做显示、排序、过滤?
您会发现对显示相关模型数据的GridView列进行排序和筛选实现起来很棘手。
正如您所知道的,如果最近一直在使用Yii2,那么有一种新的搜索数据的建议方法,即使用从主要实体模型扩展的对象,并将可搜索属性标记为“.”。那么,我们如何在GridView小部件上排序和过滤相关数据呢?
让我们想象一下下面的关系:一个叫做 “tour” 的模型:
/**
* @return \yii\db\ActiveQuery
*/
public function getCountry()
{
return $this->hasOne(Country::className(), ['id' => 'country_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getCity()
{
return $this->hasOne(City::className(), ['id' => 'city_id']);
}
我们希望在GridView上显示国家的名称和城市的名称。为了做到这一点,我们对 “tourSearch” 做了以下调整:
class TourSearch extends Tour // extends from Tour see?
{
// add the public attributes that will be used to store the data to be search
public $city;
public $country;
// now set the rules to make those attributes safe
public function rules()
{
return [
// ... more stuff here
[['city', 'country'], 'safe'],
// ... more stuff here
];
}
// ... model continues here
然后,我们配置一下 gredview,以便显示相关数据:
// ... more grid configuration here
'columns' => [
// ... more columns configuration here
[
'attribute' => 'city',
'value' => 'city.name'
],
[
'attribute' => 'country',
'value' => 'country.name'
],
如上所述,我们将能够显示数据,但如何排序或筛选?让我们举例说明,这一次让我们关注 “TearSearch” 类的 “search” 方法:
public function search($params)
{
// create ActiveQuery
$query = Tour::find();
// Important: lets join the query with our previously mentioned relations
// I do not make any other configuration like aliases or whatever, feel free
// to investigate that your self
$query->joinWith(['city', 'country']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
// Important: here is how we set up the sorting
// The key is the attribute name on our "TourSearch" instance
$dataProvider->sort->attributes['city'] = [
// The tables are the ones our relation are configured to
// in my case they are prefixed with "tbl_"
'asc' => ['tbl_city.name' => SORT_ASC],
'desc' => ['tbl_city.name' => SORT_DESC],
];
// Lets do the same with country now
$dataProvider->sort->attributes['country'] = [
'asc' => ['tbl_country.name' => SORT_ASC],
'desc' => ['tbl_country.name' => SORT_DESC],
];
// No search? Then return data Provider
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
// We have to do some search... Lets do some magic
$query->andFilterWhere([
//... other searched attributes here
])
// Here we search the attributes of our relations using our previously configured
// ones in "TourSearch"
->andFilterWhere(['like', 'tbl_city.name', $this->city])
->andFilterWhere(['like', 'tbl_country.name', $this->country]);
return $dataProvider;
}
就是这样了,希望本教程能帮助你找到方向。