Gridview 如何对关联模型的数据做显示、排序、过滤?

Wiki · 本文由 · ITer · 发布于 2年前 · 1808 阅读

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;
}

就是这样了,希望本教程能帮助你找到方向。

成为第一个本话题的爱慕者吧

评论数量:0