Laravel 4 - 雄辩。无限小孩成可用数组? [英] Laravel 4 - Eloquent. Infinite children into usable array?

查看:106
本文介绍了Laravel 4 - 雄辩。无限小孩成可用数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类别表。每个类别都可以有一个可选的父项(如果没有父项,默认为0)。



我想做的是构建一个简单的html列表树,其类别的级别。



示例日期:

 食物
- 水果
----苹果
----香蕉
----橙色
- Veg
----黄瓜
--- - 生菜
饮料
- 酒精
----啤酒
----伏特加
杂项
- 家庭对象
- ---厨房
------电气
--------烹饪
----------炉子
--- -------烤面包机
----------微波



<请注意,这需要在10个左右的水平上工作。我很喜欢它是无限的,但我真的不想在使用嵌套集合模型的路上,因为这将导致这个项目的巨大延迟。



这个文件对于laravel是可怕的,没有真正的参考,甚至从哪里开始。我已经玩了几天,试图弄清楚做什么,似乎没有任何地方没有一个巨大的混乱的每个循环在其他10次。



我在我的模型中使用以下数据我的数据树:

 <?php 
class Item扩展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个foreach循环。



我在这里做错了什么?当然这不应该是这么难/执行不力?我所要做的只是获取一个简单的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());
}

私有函数itemArray(){
$ result = array();
foreach($ this-> items as $ item){
if($ item-> parent_id == 0){
$ result [$ item-> name] = $这 - > itemWithChildren($项目);
}
}
return $ result;
}

私有函数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;
}

私有函数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(); ?>



输出如下所示:



    LI>食品
    • 水果
      • 苹果
      • 香蕉
    • 贴贴
      • 黄瓜
      • 莴苣
  • 饮料
    • 酒精
      • 啤酒
      • 伏特加
  • 其他
    • UL>
    • 厨房
      • 电气
        • 烹饪
          • 火炉
          • 烤面包机
          • 微波



注意:您的SQL小提琴有5(Orange)作为黄瓜和莴苣的parent_id,我不得不将其更改为6(Veg )。


I've got a categories table. Each category can have an optional parent (Defaults to 0 if no parent).

What I want to do is build a simple html list tree with the levels of the categories.

Example date:

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

Note that this needs to work for around 10 'levels'. I'd love it to be infinite but I really dont want to be going down the route of using a nested set model as it'll cause huge delays on this project.

The docs on this for laravel are terrible, with no real reference as to where to even start. I've been playing with it for days trying to work out what to do and seem to be getting nowhere without a huge messy block of for each loops within each other 10 times.

I've got my tree of data using the following in my model:

<?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();
    }
}

This gets all the parent and children up to a level of 10. This works fine, but you cant really then do anything with the child data without manually having 10 foreach loops within each other.

What am I doing wrong here? Surely this shouldn't be this hard/poorly executed? All I want do do is get a simple html list with the items in a tree structure.

I've put together a quick SQLFiddle example of the dummy data used above: http://sqlfiddle.com/#!2/e6d18/1

解决方案

This was much more fun than my usual morning crossword puzzle. :)

Here is an ItemsHelper class that will do what you are looking for, and better yet will recurse as far down as you want.

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;
    }
  }

I just used a new installation of Laravel 4 and the basic hello.php view.

Here is my route in app/routes.php:

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

Although my view doesn't use the items variable, I'm passing it here because you probably will want to do something else with them too.

And finally, my app/views/hello.php just has one line:

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

The output looks like this:

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

Note: your SQL Fiddle had 5 ("Orange") as the parent_id for Cucumber and Lettuce, I had to change it to 6 ("Veg").

这篇关于Laravel 4 - 雄辩。无限小孩成可用数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆