Передача коллекции/массива моделей в CActiveDataProvider.

Обсуждение документации. Переводы Cookbook и авторские рецепты.
Ответить
Johnatan
Сообщения: 167
Зарегистрирован: 2010.10.27, 13:06
Откуда: Reino de España

Передача коллекции/массива моделей в CActiveDataProvider.

Сообщение Johnatan »

Приветствую,
я знаю, что у многих новичков (и не только) возникает вопрос, как передать в CActiveDataProvider уже готовый набор моделей, например из отношения основной модели ($item->children, где children это отношение MANY_MANY или HAS_MANY). Чаще всего этот вопрос возникает для отображения данных в CGridView.

Решение проблемы заключается в понимании концепции CActiveDataProvider, для чего он нужен и как им пользоваться. Фактически CActiveDataProvider является построителем SQL запросов для фильтрации и сортировки данных из БД. Он не может принимать готовые коллекции, так как он сам выбирает эти коллекции из БД в зависимости от критериев и сортировки заданных пользователем.
Для того, чтобы отобразить в CGridView уже существующий набор данных нужно просто использовать CArrayDataProvider. Этот класс в свою очередь принимает как массивы чистых данных, так и массивы моделей. Основное отличие использования CArrayDataProvider от CActiveDataProvider, это то, что первый не предоставляет возможности фильтрации (фильтрация должна быть произведена ДО передачи массива моделей в конструктор класса). Чаще всего такой формат используется, когда нужно показать данные в гриде без использования фильтра (список товаров в смете, статичные списки и т.д.) Если вы хотите фильтровать данные через грид, то придётся использовать CActiveDataProvider.

Я надеюсь кому-нибудь данное объяснение поможет избежать потери кучи времени.
Конференция: [email protected]
andreyrud
Сообщения: 265
Зарегистрирован: 2011.09.26, 14:59

Re: Передача коллекции/массива моделей в CActiveDataProvider

Сообщение andreyrud »

Я правильно понял, что CArrayDataProvider отключает возможности поиска, сортировки и ... в CGridView?

А есть ли в yii "виртуальная" модель? Модель, составленная на основе разных сложных отношений многих реальных моделей. Наподобие view(представлений) в SQL? Что бы можно было полноценно работать с такой моделью как с реальной простой таблицей без постоянной возни с отношениями и иметь в CGridView все его вкусности?
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Передача коллекции/массива моделей в CActiveDataProvider

Сообщение rak »

andreyrud писал(а):Я правильно понял, что CArrayDataProvider отключает возможности поиска, сортировки и ... в CGridView?
Нет. Сортировка и поиск происходит в php, а не на уровне БД
andreyrud писал(а): А есть ли в yii "виртуальная" модель? Модель, составленная на основе разных сложных отношений многих реальных моделей. Наподобие view(представлений) в SQL? Что бы можно было полноценно работать с такой моделью как с реальной простой таблицей без постоянной возни с отношениями и иметь в CGridView все его вкусности?
Нет, нету
Данил
Сообщения: 13
Зарегистрирован: 2013.06.10, 12:20

Re: Передача коллекции/массива моделей в CActiveDataProvider

Сообщение Данил »

Johnatan писал(а):Приветствую,
я знаю, что у многих новичков (и не только) возникает вопрос, как передать в CActiveDataProvider уже готовый набор моделей, например из отношения основной модели ($item->children, где children это отношение MANY_MANY или HAS_MANY). Чаще всего этот вопрос возникает для отображения данных в CGridView.

Решение проблемы заключается в понимании концепции CActiveDataProvider, для чего он нужен и как им пользоваться. Фактически CActiveDataProvider является построителем SQL запросов для фильтрации и сортировки данных из БД. Он не может принимать готовые коллекции, так как он сам выбирает эти коллекции из БД в зависимости от критериев и сортировки заданных пользователем.
Для того, чтобы отобразить в CGridView уже существующий набор данных нужно просто использовать CArrayDataProvider. Этот класс в свою очередь принимает как массивы чистых данных, так и массивы моделей. Основное отличие использования CArrayDataProvider от CActiveDataProvider, это то, что первый не предоставляет возможности фильтрации (фильтрация должна быть произведена ДО передачи массива моделей в конструктор класса). Чаще всего такой формат используется, когда нужно показать данные в гриде без использования фильтра (список товаров в смете, статичные списки и т.д.) Если вы хотите фильтровать данные через грид, то придётся использовать CActiveDataProvider.

Я надеюсь кому-нибудь данное объяснение поможет избежать потери кучи времени.
Огромное Вам спасибо за объяснение. Весь вечер пытался сделать вот так
$dataProvider=new CActiveDataProvider($relatedPosts, array(
'pagination'=>array(
'pageSize'=>5,
),
Пока не наткнулся на этот пост :) Уже хотел тему создавать
Аватара пользователя
Neuromance
Сообщения: 716
Зарегистрирован: 2011.09.06, 13:04

Re: Передача коллекции/массива моделей в CActiveDataProvider

Сообщение Neuromance »

В моем проекте не могу использовать CActiveDataProvider. Пользуюсь CArrayDataProvider. Для того, чтобы была возможность фильтровать и сортировать в гриде написал следующую приблуду(может кому пригодится)

Код: Выделить всё

//класс RCGridView (расширение CGridView)
....
protected function initColumns(){
  ...
  if($this->dataProvider instanceof CArrayDataProvider) {
      $this->dataProvider->attachBehavior('search', 'CArrayDataProviderSearch');
      ...
      //здесь в зависимости от типа фильтра в колонке заполняем переменную $cfilter
      foreach($this->columns as $i=>$column){
         if(isset($column['dropDownFilter']) && $column['dropDownFilter'] && isset($column['name'])) {
           $cfilter = ....
        }
        elseif(isset($column['textFilter']) && $column['textFilter'] && isset($column['name'])){
          $cfilter = ...
        }
      }
     ...
      this->dataProvider = $this->dataProvider->search($this->dataProvider, $cfilter);
    }
  ...
}

....

Код: Выделить всё

class CArrayDataProviderSearch extends CBehavior{
  public function search($data, $condition){
    //здесь в зависимости от $condition удаляем лишние записи из $data
   retyrn $data;
  }
malik mohsin
Сообщения: 1
Зарегистрирован: 2013.09.06, 09:20

Re: Передача коллекции/массива моделей в CActiveDataProvider

Сообщение malik mohsin »

:P This post is so great and nice :oops:

Огромное Вам спасибо за объяснение. Весь вечер пытался сделать вот так
$dataProvider=new CActiveDataProvider($relatedPosts, array(
'pagination'=>array(
petr_yalta
Сообщения: 2
Зарегистрирован: 2014.02.27, 16:15

Re: Передача коллекции/массива моделей в CActiveDataProvider

Сообщение petr_yalta »

Объясните мне пожалуйста, почему при одинаковых критериях выдаются разные результаты ?
Сделал для этого отдельную тему viewtopic.php?f=27&t=16931
Ответить