Добрый день. Есть таблица со списком элементов. Каждый элемент может иметь родителя из этой же таблицы.
в таблице
id name parent
1 Child1ofParent0 0
2 Child1ofParent1 1
3 Child2ofParent1 1
4 Child2ofParent0 1
5 Child1ofParent2 4
...
То есть простейшая структура - где parent - id родительского элемента
Подскажите пожалуйста, как вывести GridView в виде
Parent1
Child1ofParent1
Child2ofParent1
Child3ofParent1
Parent2
Child1ofParent2
Child2ofParent2
Child3ofParent2
....
То есть сначала выводится родитель, затем все дочерние элементы (у которых paren = id родителя), потом следующий. Вложеность только на 1 ребенка. Дальше подкатегорий нет
GridView отсортированный список parent/child
-
- Сообщения: 1
- Зарегистрирован: 2018.10.23, 20:20
- proctoleha
- Сообщения: 298
- Зарегистрирован: 2016.07.10, 19:00
Re: GridView отсортированный список parent/child
Вообще проще один раз изучить Nested Sets (Вложенные множества), и не париться с детьми и родителями.
Но ситуации бывают разные, и в одном из проектов, мне потребовалось решить такую же задачу - вывести упорядоченный плоский список в GridView, ориентируясь на id и pid
Написал небольшой костыль, вспомнив, при этом, как можно нестандартно объявлять переменные в php и присваивание значений по ссылке.
1. У нас есть объект класса ActiveDataProvider, причем сортируем данные сначала по pid ASC, это важно. В выборке у нас сначала идут строки с pid = null, например метод класса OrdersSearch, который ищет отгруженные заказы:
2. В контроллере почти всё стандартно
Только появился метод changeShippedModels.
3. В этом методе мы вытаскиваем массив моделей из объекта класса ActiveDataProvider, и приводим этот массив к нужному нам виду. Внимание! По условию задачи у нас только один уровень вложенности!
Код прозрачный, если что-то непонятно - медитируем. Но, вообще это костыль. Гораздо проще работать с nested sets. Даже если всего один ребенок.
Но ситуации бывают разные, и в одном из проектов, мне потребовалось решить такую же задачу - вывести упорядоченный плоский список в GridView, ориентируясь на id и pid
Написал небольшой костыль, вспомнив, при этом, как можно нестандартно объявлять переменные в php и присваивание значений по ссылке.
1. У нас есть объект класса ActiveDataProvider, причем сортируем данные сначала по pid ASC, это важно. В выборке у нас сначала идут строки с pid = null, например метод класса OrdersSearch, который ищет отгруженные заказы:
Код: Выделить всё
public function searchShipped($params)
{
$query = Order::find()
->where(['user_id' => $this->user_id])
->andWhere(['>=', 'status', Order::STATUS['part_shipped']['value']]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => [
'defaultOrder' => ['pid' => SORT_ASC, 'created_at' => SORT_DESC],
]
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
$query->andFilterWhere(['status' => $this->status]);
$query->andFilterWhere(['like', 'number', $this->number]);
return $dataProvider;
}
Код: Выделить всё
public function actionShipped($user_id)
{
$searchModel = new OrdersSearch($user_id);
$dataProvider = $searchModel->searchShipped(\Yii::$app->request->queryParams);
$searchModel->changeShippedModels($dataProvider);
return $this->render('shipped', [
'dataProvider' => $dataProvider,
'searchModel' => $searchModel,
]);
}
3. В этом методе мы вытаскиваем массив моделей из объекта класса ActiveDataProvider, и приводим этот массив к нужному нам виду. Внимание! По условию задачи у нас только один уровень вложенности!
Код: Выделить всё
public function changeShippedModels(ActiveDataProvider $dataProvider)
{
/** @var Order[] $models */
$models = $dataProvider->getModels();
$modelsNew = [];
$data = [];
foreach ($models as $model) {
if (!$model->pid) {
${'parent' . $model->id}[] = $model;
$data[] = &${'parent' . $model->id};
} else {
${'parent' . $model->pid}[] = $model;
}
}
foreach ($data as $item) {
foreach ($item as $i) {
$modelsNew[] = $i;
}
}
$dataProvider->setKeys(ArrayHelper::getColumn($modelsNew, 'id'));
$dataProvider->setModels($modelsNew);
}
Вот за что я не люблю линукс, так это за свои кривые, временами, руки