Intereting Posts
Функция PHP использует переменную извне Отдельное здание от развертывания с помощью Хадсона Угловая и CodeIgniter Validation Library Откройте страницу iframe в своем родителе, когда прямая ссылка относится к одной из дочерних страниц Функция JavaScript не обновляет списки на веб-странице при выпадающем элементе PHP regex заменяет пустое пространство на & nbsp; если он соответствует одной букве mysql зажимает определенные символы и mssql не Использовать браузер для кэширования изображений Сравнение переменных PHP .htaccess php_value auto_prepend_file делает ошибку 500. Как я могу это исправить? php mcrypt – дешифрование и шифрование файлов? Как изменить пустую строку на нуль, используя Laravel 5.1? DDD – сохраняющиеся агрегированные дети только при изменении PHP: iPad не воспроизводит видеоролики MP4, поставляемые PHP, но при непосредственном доступе он делает Запустить php-код в командной строке

Laravel 4 – Красноречивый. Бесконечные дети в полезный массив?

У меня есть таблица категорий. Каждая категория может иметь необязательный родительский (по умолчанию – 0, если нет родителя).

Я хочу создать простое дерево списка html с уровнями категорий.

Пример:

Foods -- Fruit ---- Apple ---- Banana ---- Orange -- Veg ---- Cucumber ---- Lettuce Drinks -- Alcoholic ---- Beer ---- Vodka Misc -- Household Objects ---- Kitchen ------ Electrical -------- Cooking ---------- Stove ---------- Toaster ---------- Microwave 

Обратите внимание, что это должно работать примерно на 10 уровней. Я бы хотел, чтобы это было бесконечно, но я действительно не хочу идти по пути использования вложенной модели набора, так как это вызовет огромные задержки в этом проекте.

Документы по этому поводу для laravel ужасны, без реальной ссылки на то, где даже начать. Я играю с ним в течение нескольких дней, пытаясь понять, что делать, и, кажется, никуда не денется без огромного беспорядочного блока для каждой петли внутри друг друга 10 раз.

Я получил свое дерево данных, используя следующее в моей модели:

 <?php class Item extends Eloquent { public function parent() { return $this->hasOne('Item', 'id', 'parent_id'); } public function children() { return $this->hasMany('Item', 'parent_id', 'id'); } public function tree() { return static::with(implode('.', array_fill(0,10, 'children')))->where('parent_id', '=', '0')->get(); } } 

Это приводит к тому, что все родители и дети достигнут уровня 10. Это прекрасно работает, но вы не можете делать что-либо с дочерними данными, не имея вручную вручную 10 петель.

Что я здесь делаю неправильно? Неужели это не должно быть так сложно / плохо выполнено? Все, что я хочу сделать, это получить простой список html с элементами в древовидной структуре.

Я собрал быстрый пример SQLFiddle из фиктивных данных, используемых выше: http://sqlfiddle.com/#!2/e6d18/1

Это было намного веселее, чем моя обычная утренняя кроссворд. 🙂

Вот класс ItemsHelper, который будет делать то, что вы ищете, и, тем не менее, еще лучше забеременеть так далеко, как вы хотите.

app/models/ItemsHelper.php:

 <?php class ItemsHelper { private $items; public function __construct($items) { $this->items = $items; } public function htmlList() { return $this->htmlFromArray($this->itemArray()); } private function itemArray() { $result = array(); foreach($this->items as $item) { if ($item->parent_id == 0) { $result[$item->name] = $this->itemWithChildren($item); } } return $result; } private function childrenOf($item) { $result = array(); foreach($this->items as $i) { if ($i->parent_id == $item->id) { $result[] = $i; } } return $result; } private function itemWithChildren($item) { $result = array(); $children = $this->childrenOf($item); foreach ($children as $child) { $result[$child->name] = $this->itemWithChildren($child); } return $result; } private function htmlFromArray($array) { $html = ''; foreach($array as $k=>$v) { $html .= "<ul>"; $html .= "<li>".$k."</li>"; if(count($v) > 0) { $html .= $this->htmlFromArray($v); } $html .= "</ul>"; } return $html; } } 

Я просто использовал новую установку Laravel 4 и основной вид hello.php .

Вот мой маршрут в app/routes.php :

 Route::get('/', function() { $items = Item::all(); $itemsHelper = new ItemsHelper($items); return View::make('hello',compact('items','itemsHelper')); }); 

Хотя мое представление не использует переменную items, я передаю ее здесь, потому что вы, вероятно, захотите сделать что-то еще с ними.

И, наконец, мое app/views/hello.php имеет только одну строку:

<?= $itemsHelper->htmlList(); ?>

Результат выглядит следующим образом:

  • Продукты
  • Фрукты
  • яблоко
  • Банан
  • оранжевый
  • Вег
  • Огурец
  • Салат
  • напитки
  • алкоголик
  • Пиво
  • Водка
  • Разное
  • Домашние предметы
  • Кухня
  • электрический
  • Готовка
  • Плита
  • Тостер
  • СВЧ

Примечание: ваш SQL Fiddle имел 5 («Оранжевый») в качестве parent_id для Cucumber и Lettuce, мне пришлось изменить его на 6 («Veg»).

Я использую эти функции, чтобы заставить его работать.

  //Returns Root elements public function scopeRoot($query) { $all = $query->whereParent(0)->get(); $collection = $all->filter(function($single) { if ($single->ModelFilter('GET')) { return $single; } }); return $collection; } //Recursive call public function traverse() { self::_traverse($this->Children, $array, $this); return $array; } //This function build a multidimensional array based on a collection of elements private static function _traverse($collection, &$array, $object) { $new_array = array(); foreach ($collection as $element) { self::_traverse($element->Children, $new_array, $element); } $array[] = $object; if (count($new_array) > 0) { $array[] = $new_array; } } 

Сначала я получаю коллекцию корневых элементов, которые я передаю своим представлениям, где я хочу перечислить дерево …

Тогда я …

  <ul class="bg-info cat-list"> @foreach($categories as $category) <?php $array = $category->traverse(); list_view($array); ?> @endforeach </ul> 

Используя эту функцию …

 //Prints a multidimensional array as a nested HTML list function list_view($element, $ul = true) { foreach ($element as $value) { if (!is_array($value)) { echo "<li>"; echo $value->name; } else { echo ($ul) ? "<ul>" : "<ol>"; list_view($valuce, $ul); echo "</li>"; echo ($ul) ? "</ul>" : "</ol>"; } } } 

Вывод

Надеюсь, поможет

Я расширил принятый ответ Марка Смита, чтобы разрешить сгенерированные списки ссылаться на дополнительные данные, которые передаются в класс.

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

Просто укажите вспомогательный класс в контроллере:

 use App\Helpers\CategoryHierarchy; 

Затем вы можете либо создать экземпляр класса вручную, либо использовать метод Laravel 5 для впрыскивания.

 $products = $product->getAllProducts(); $hierarchy->setupItems($products); return $hierarchy->render(); 

Это может вывести следующее:

 <ul class='simple-list'> <li><input type="checkbox" name="hierarchy-checkboxes[]" value="1" >Home delivery</li> <ul> <li><input type="checkbox" name="hierarchy-checkboxes[]" value="2" >Italian</li> <ul> <li><input type="checkbox" name="hierarchy-checkboxes[]" value="3" >Pizza</li> <li><input type="checkbox" name="hierarchy-checkboxes[]" value="4" >Pasta</li> </ul> <li><input type="checkbox" name="hierarchy-checkboxes[]" value="5" >Burgers</li> </ul> </ul> 

Доступно репо: https://github.com/drawmyattention/CategoryHierarchy, который объясняет более подробно.