如何在Laravel中创建嵌套的类别列表?

问题描述 投票:4回答:4

如何在Laravel中创建嵌套的类别列表?

我想创建类似这样的例子:

  • --- Php
  • ------ Laravel
  • ---------版本
  • ------------ V 5.7
  • --- Python
  • ------ Django
  • --- Ruby
  • ..........

我的表的字段是:

id | name | parent_id

如果我必须在深度上添加另一列到我的表中,请告诉我。

我正在使用以下代码,但我认为它不是创建嵌套列表类别的最佳解决方案,我不能将此函数传递给我的视图:

function rec($id)
{
     $models = Category::find($id);

     foreach ($models->children as $chield) {
          rec($chield->id);
     }

     return $models->all();
}

function main () {
    $models = Category::whereNull('parent_id')->get();

    foreach ($models as $parent) {
       return rec($parent->id);
    }
}
php laravel nested-lists
4个回答
9
投票

你可以做一个自我指涉的模型:

class Category extends Model {

    public function parent()
    {
        return $this->belongsTo('Category', 'parent_id');
    }

    public function children()
    {
        return $this->hasMany('Category', 'parent_id');
    }
}

并建立递归关系:

// recursive, loads all descendants
public function childrenRecursive()
{
   return $this->children()->with('childrenRecursive');
}

并让父母带着他们所有的孩子:

$categories = Category::with('childrenRecursive')->whereNull('parent')->get();

最后,您需要遍历子项,直到子项为空。如果你不小心,肯定会遇到一些性能问题。如果这是一个相当小的数据集,您计划保持这种方式,那么它应该不是问题。如果这将成为一个不断增长的列表,有一个root_parent_id或其他东西可以查询并手动组装树可能是有意义的。


0
投票

在这个领域以某种方式搜索某些东西我想分享一个获得孩子深度水平的功能:

    function getDepth($category, $level = 0) {
    if ($category->parent_id>0) {
        if ($category->parent) {
                $level++;
                return $this->getDepth($category->parent, $level);
            }
        }
       return $level;
    }

也许它会帮助别人!干杯!


0
投票

问题已经解决了!

视图:

    $traverse = function ($categories) use (&$traverse) {
        foreach ($categories as $category) {
            $traverse($cat->Children);
        }
    };
    $traverse(array ($category));

模型:

public function Children()
{
    return $this->hasMany($this, 'parent');
}

public function Parent()
{
    return $this->hasOne($this,'id','parent');
}

0
投票

如果有人需要更好的答案,请查看我的答案,当我面对这样的问题时,它帮助了我。

   class Category extends Model {

     private $descendants = [];

     public function children()
        {
            return $this->subcategories()->with('children');
        }

     public function hasChildren(){
            if($this->children->count()){
                return true;
            }

            return false;
        }

     public function findDescendants(Category $category){
            $this->descendants[] = $category->id;

            if($category->hasChildren()){
                foreach($category->children as $child){
                    $this->findDescendants($child);
                }
            }
        }

      public function getDescendants(Category $category){
            $this->findDescendants($category);
            return $this->descendants;
        }
 }

在你的控制器中只测试一下:

$category = Category::find(1);
$category_ids = $category->getDescendants($category);

它将导致数组中所有id = 1的后代的数组。然后 :

$products = Product::whereIn('category_id',$category_ids)->get();

不客气=)

© www.soinside.com 2019 - 2024. All rights reserved.