Yii2 GridView与ArrrayDataProvider搜索

问题描述 投票:0回答:1

我需要有关ArrayDataProvider的搜索模型的帮助。假设我有一个数组:

$cities = [
    ['city' => "Chicago", 'year' => 1984],
    ['city' => "Washington", 'year' => 2001],
    ['city' => Manchester", 'year' => 1997],
    //and so on...
];

我创建了一个ArrayDataProvider:

$provider = new \yii\data\ArrayDataProvider([
    'allModels' => $catalog,
    'sort' => [
        'attributes' => ['city', 'year'],
    ],
]); 

然后我创建一个GridView:

echo \yii\grid\GridView::widget([
        'dataProvider' => $provider,
        'filterModel' => (new LibrarySearchModel()),
        'columns' => $columns,
        'showHeader' => true,
        'summary' => false,
    ]);

一切正常,但我需要在GridView中进行过滤。没有选项可以使用ActiveDataProvider,我找不到任何教程如何过滤ArrayDataProvider中的数据。有人可以帮助我使用过滤器模型的代码或为我的案例推荐文档吗?

php yii2
1个回答
1
投票

这是如何在ArrayDataProvider中使用GridView和过滤器的示例。

让我们创建简单的动作。

public function actionExample()
{
    $data = new \app\models\Data();
    $provider = $data->search(Yii::$app->request->get());

    return $this->render('example', [
        'provider' => $provider,
        'filter' => $data,
    ]);
}

这是GridView的经典Yii 2方法,因此我不会解释它(您可以在上面链接的指南中找到详细信息)。

现在看来。

<?php

echo \yii\grid\GridView::widget([
    'dataProvider' => $provider,
    'filterModel' => $filter,
    'columns' => [
        'name',
        'code',
    ],
]);

同样,与ActiveDataProvider方法没什么不同。正如您在此处所见,我们期待两列:namecode - 这些将在下面定义。

Data模型。

准备将处理数据源的模型。注释中给出了解释。

<?php

namespace app\models;

use yii\base\Model;

/**
 * Our data model extends yii\base\Model class so we can get easy to use and yet 
 * powerful Yii 2 validation mechanism.
 */
class Data extends Model
{
    /**
     * We plan to get two columns in our grid that can be filtered.
     * Add more if required. You don't have to add all of them.
     */
    public $name;
    public $code;

    /**
     * Here we can define validation rules for each filtered column.
     * See http://www.yiiframework.com/doc-2.0/guide-input-validation.html
     * for more information about validation.
     */
    public function rules()
    {
        return [
            [['name', 'code'], 'string'],
            // our columns are just simple string, nothing fancy
        ];
    }

    /**
     * In this example we keep this special property to know if columns should be 
     * filtered or not. See search() method below.
     */
    private $_filtered = false;

    /**
     * This method returns ArrayDataProvider.
     * Filtered and sorted if required.
     */
    public function search($params)
    {
        /**
         * $params is the array of GET parameters passed in the actionExample().
         * These are being loaded and validated.
         * If validation is successful _filtered property is set to true to prepare
         * data source. If not - data source is displayed without any filtering.
         */
        if ($this->load($params) && $this->validate()) {
            $this->_filtered = true;
        }

        return new \yii\data\ArrayDataProvider([
            // ArrayDataProvider here takes the actual data source
            'allModels' => $this->getData(),
            'sort' => [
                // we want our columns to be sortable:
                'attributes' => ['name', 'code'],
            ],
        ]);
    }

    /**
     * Here we are preparing the data source and applying the filters
     * if _filtered property is set to true.
     */
    protected function getData()
    {
        $data = [
            ['name' => 'Paul', 'code' => 'abc'],
            ['name' => 'John', 'code' => 'ade'],
            ['name' => 'Rick', 'code' => 'dbn'],
        ];

        if ($this->_filtered) {
            $data = array_filter($data, function ($value) {
                $conditions = [true];
                if (!empty($this->name)) {
                    $conditions[] = strpos($value['name'], $this->name) !== false;
                }
                if (!empty($this->code)) {
                    $conditions[] = strpos($value['code'], $this->code) !== false;
                }
                return array_product($conditions);
            });
        }

        return $data;
    }
}

此示例中的过滤由array_filter函数处理。两列都经过过滤“数据库LIKE”样式 - 如果列值包含搜索到的字符串,则不会从源中删除data数组行。

为了使它像ActiveDataProvider中的and条件一样工作,我们在$conditions数组中放入每列检查的布尔结果,并在array_filter中返回该数组的产品。

array_product($conditions)相当于写$conditions[0] && $conditions[1] && $conditions[2] && ...

这都导致了具有两列的可过滤和可排序的GridView小部件。

© www.soinside.com 2019 - 2024. All rights reserved.