1

我的地址控制器:

public function actionIndex() {
    $searchModel = new AddressSearch;
    $dataProvider = $searchModel->search($_GET);

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

我的模型地址搜索:

class AddressSearch extends Model {

    public function search($params) {
        $dataProvider = new SqlDataProvider([
            'sql' => '
                SELECT
                    name
                FROM...

看法:

GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        'name2',

我有一个name在 this中调用的属性dataProvider。我想创建一个新的虚拟属性,调用它name2的几个部分。该功能本身正在运行。我尝试了很多不同的东西,但我仍然无法用数据填充属性。总是空的。你能指出我正确的方向吗?非常感谢!namepreg_replace()name2name2

更新:基于@Imaginaroom 和@rob006 的绝妙想法,我做了以下事情:

  • 移动getName2()和我填充的属性SqlDataProvider从基本模型AddressAddressSearch
  • 删除了空的基本模型Address,因为无论如何我都不需要它。少即是多!
  • search()我添加了:

    foreach ($dataProvider->getModels() as $row) {
        $model = new AddressSearch;
        $model->setAttributes($row, false);
        $models[] = $model;
    }
    $dataProvider->setModels($models);
    

有用!非常感谢你们!你在那里并提供帮助真是太棒了!!!

4

2 回答 2

1

问题是您使用SqlDataProviderwhich 从表中返回行作为数组而不是模型实例。这就是为什么您的 getter(虚拟属性)不起作用的原因GridView-GridView不适用于模型实例,但不适用于没有字段Address的原始数组。name2

你应该改变你SearchModel的使用ActiveQuery

$dataProvider = ActiveDataProvider([
    'query' => Address::find()->select(['name']) //and whatever your query contains besides this
])
...

更新:如果你不想这样做,你可以GridView像这样直接添加你的逻辑:

GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        [
            'header' => 'Name 2',
            'value' => function($model) {
                if (isset($this->_name2)) {
                    return $this->_name2;
                }

                return $this->_name2 = preg_replace([...
            }
        ]
于 2018-09-14T06:47:12.307 回答
1

如果您确实需要Address模型实例并同时使用SqlDataProvider,您可以手动将数组转换为模型实例:

$models = [];
foreach ($dataProvider->getModels() as $row) {
    $model = Address::instantiate($row);
    Address::populateRecord($model, $row);
    $models[] = $model;
}
$dataProvider->setModels($models);

您可以将其放入AddressSearch::search()或创建自定义SqlDataProvider和覆盖prepareModels()

于 2018-09-14T08:45:06.107 回答