kartik tree (nested-sets). Как создать дерево для frontend?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Аватара пользователя
ninzzo
Сообщения: 348
Зарегистрирован: 2014.04.25, 07:29

kartik tree (nested-sets). Как создать дерево для frontend?

Сообщение ninzzo »

В backend использую виджет для создания категорий. Все отлично работает.

Хочу во фронтенде просто сделать дерево не используя виджет.

Беру таблицу:(которая уже заполнена в backend)

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

CREATE TABLE table (
    id            INT(11)      NOT NULL AUTO_INCREMENT PRIMARY KEY,
    root          INT(11)               DEFAULT NULL,
    lft           INT(11)      NOT NULL,
    rgt           INT(11)      NOT NULL,
    lvl           SMALLINT(5)  NOT NULL,
    name          VARCHAR(60)  NOT NULL,
    ...
    
   Создаю модель для frontend:
   class Category extends \yii\db\ActiveRecord {
   ...
   }
    
Контроллер что бы построить дерево:

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


    public static function getMenuItems(array $models = null)
    {

        $items = [];

        //создаем первый круг
        if ($models === null) {
            $models = Category::find()->where(['lvl' => 0, 'active'=>1])->all();
        }        
       
        foreach ($models as $model) {
            $items[] = [
                'url' => ['material/category', 'id' => $model->id],
                'label' => $model->name,
                'items' => self::getMenuItems(Category::find()->where(['active'=>1, 'root' => $model->id])->all()),
            ];
        }

        return $items;
    }
    
Запускаю и бесконечно грузится.
Если делаю для теста:

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

 'items' => self::getMenuItems(Category::find()->where(['active'=>1, 'root' => $model->id])->one()),
получаю
"Argument 1 passed to ...MaterialController::getMenuItems() must be of the type array, object given, called in ..."

Как написать правильно эту рекурсивную функцию ? Не могу найти ошибку.
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: kartik tree (nested-sets). Как создать дерево для frontend?

Сообщение mkramer »

Вообще, nested sets придумали для того, чтобы избежать рекурсии. Она тут не нужна. Картик над этим расширением же оболочку сделал, насколько мне помнится. https://github.com/creocoder/yii2-nested-sets Посмотри, как там детей получать. Они вместе с внуками и правнуками сразу, всё дерево за один проход
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: kartik tree (nested-sets). Как создать дерево для frontend?

Сообщение mkramer »

Во фронте модель подключает nested-set поведение?
Аватара пользователя
ninzzo
Сообщения: 348
Зарегистрирован: 2014.04.25, 07:29

Re: kartik tree (nested-sets). Как создать дерево для frontend?

Сообщение ninzzo »

Вообще, nested sets придумали для того, чтобы избежать рекурсии. Она тут не нужна. Картик над этим расширением же оболочку сделал, насколько мне помнится. https://github.com/creocoder/yii2-nested-sets Посмотри, как там детей получать. Они вместе с внуками и правнуками сразу, всё дерево за один проход
creocoder/yii2-nested-sets пробовал:
-Те методы что описаны у картика не работают.
-Таблица что создается в yii2-nested-sets отличается от таблицы картика (Там depth,tree. Тут root, lvl).
-Если закачать "php composer.phar require kartik-v/yii2-tree-manager "@dev"", а потом "composer require creocoder/yii2-nested-sets" вылазит ошибка composer "не сходятся какие то минимальные максимальные версии бла бла бла" и ничего не качается.
Во фронте модель подключает nested-set поведение?
ну у меня две модели.
одна наследует картика - class MarketCateg extends \kartik\tree\models\Tree
вторая просто AR - class MarketCategFront extends \yii\db\ActiveRecord

Пробую строить рекурсию, пока что не получается ни с одной ни с другой.
Пробовал получить потомков через методы nested-sets - они не работают(я думаю их просто нет у картика).

Но я запили велосипед)
Аватара пользователя
ninzzo
Сообщения: 348
Зарегистрирован: 2014.04.25, 07:29

Re: kartik tree (nested-sets). Как создать дерево для frontend?

Сообщение ninzzo »

Вот как можно построить дерево Nested set из AR:(если нужно)

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

ModelForNested::find()->addOrderBy('root, lft')->all(),
$level=0;

foreach($menuItems as $n=>$category)
{
    if($category->lvl==$level)
    	echo '</li>';
    else if($category->lvl>$level)
        echo '<ul>';
    else
    {
        echo '<li>';

        for($i=$level-$category->lvl;$i;$i--)
        {
            echo '</ul>';
            echo '</li>';
        }
    }

    echo '<li>';
    echo $category->name;
    $level=$category->lvl;
}

for($i=$level;$i;$i--)
{
    echo '</li>';
    echo '</ul>';
}
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: kartik tree (nested-sets). Как создать дерево для frontend?

Сообщение mkramer »

ninzzo писал(а): 2017.06.16, 13:16
creocoder/yii2-nested-sets пробовал:
-Те методы что описаны у картика не работают.
-Таблица что создается в yii2-nested-sets отличается от таблицы картика (Там depth,tree. Тут root, lvl).
Всё там работает, и никакая рекурсия не нужна. Расширение картика тянет yii2-nested-sets по дефолту, и уже подключает это поведение. То, что там поля переименованы - так расширение yii2-nested-sets делает это. Цель использовать другую модель во фронте? Я ещё понимаю, если бы ты вообще от ActiveRecord во фронте отказался...
Аватара пользователя
ninzzo
Сообщения: 348
Зарегистрирован: 2014.04.25, 07:29

Re: kartik tree (nested-sets). Как создать дерево для frontend?

Сообщение ninzzo »

Всё там работает, и никакая рекурсия не нужна. Расширение картика тянет yii2-nested-sets по дефолту, и уже подключает это поведение. То, что там поля переименованы - так расширение yii2-nested-sets делает это. Цель использовать другую модель во фронте? Я ещё понимаю, если бы ты вообще от ActiveRecord во фронте отказался...
так я на фронте наоборот сделал через AR.
Модель у картика extends \kartik\tree\models\Tree в котором yii2-nested-sets только в теории.

Все там работает ?
Если модель Menu extends \kartik\tree\models\Tree
$roots = Menu::find()->roots()->all(); - работает
$leaves = Menu::find()->leaves()->all(); - не работает

$countries = Menu::findOne(['name' => 'Countries']);
$leaves = $countries->leaves()->all(); - не работает


$countries = Menu::findOne(['name' => 'Countries']);
$children = $countries->children()->all(); - не работает

дальше не проверял.
Optim1zer
Сообщения: 6
Зарегистрирован: 2017.06.16, 11:04

Re: kartik tree (nested-sets). Как создать дерево для frontend?

Сообщение Optim1zer »

Я сталкивался с таким.
Выборку сделал так:

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

$items = Menu::find()
            ->andWhere(['active' => 1])
            ->addOrderBy('root, lft')
            ->asArray()
            ->all();
Затем группируем записи для каждого дерева и выводим их.
Ответить