Laravel 4 - 雄辩.无限儿童成可用阵列?

Sk4*_*446 11 php parent-child laravel eloquent 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
Run Code Online (Sandbox Code Playgroud)

请注意,这需要适用于大约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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这使得所有父级和子级达到10级.这样可以正常工作,但是您无法对子数据执行任何操作,而无需在彼此之间手动设置10个foreach循环.

我在这做错了什么?当然这应该不是这么难/执行不好?我想要做的就是获得一个简单的html列表,其中包含树结构中的项目.

我已经把上面使用的虚拟数据的快速SQLFiddle示例放在一起:http://sqlfiddle.com/#!2/e6d18/1

Mar*_*ith 39

这比我平常的早上填字游戏更有趣.:)

这是一个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;
    }
  }
Run Code Online (Sandbox Code Playgroud)

我刚刚使用了Laravel 4的新安装和基本hello.php视图.

这是我的路线app/routes.php:

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

虽然我的视图不使用items变量,但我在这里传递它是因为你可能也想用它们做其他事情.

最后,我app/views/hello.php只有一行:

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

输出如下所示:

  • 食品
    • 水果
      • 苹果
      • 香蕉
      • 橙子
    • 素食
      • 黄瓜
      • 生菜
  • 饮料
    • 酒精
      • 啤酒
      • 伏特加
  • 杂项
    • 家居用品
      • 厨房
        • 电动
          • 烹饪
            • 火炉
            • 烤面包机
            • 微波

注意:你的SQL Fiddle有5个("Orange")作为Cucumber和Lettuce的parent_id,我不得不将它改为6("Veg").

  • 你太客气了!很高兴我可以帮忙. (2认同)