如何在 Laravel 的下拉菜单 (select) 中打印无限嵌套类别

How to print infinity nested categories in dropdown (select) menu in Laravel

我有这个 category table:

id name parent_id
1 Programming 0
2 History 0
3 PHP 1
4 Javascript 1
6 World history 2
7 jQuery 4
8 AJAX 4
9 Europe 6
10 American 6
16 ajax nested 8

以下是我如何在 控制器 中获取类别:

$categories = Category::where('parent_id', '=', 0)->with('childs')->get();

模特类别:

class Category extends Model
{
    use HasFactory;

    protected $fillable = ['name'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function posts()
    {
        return $this->hasMany(Post::class)->orderBy('created_at', 'DESC');
    }

    public function childs()
    {
        return $this->hasMany(Category::class, 'parent_id', 'id');
    }
}

我想输出类别,像这样:

<select>
<option id="1">Programming</option>
<option id="3">Programming -> PHP</option>
<option id="4">Programming -> Javascript</option>
<option id="7">Programming -> Javascript -> jQuery</option>
<option id="8">Programming -> Javascript -> AJAX</option>
<option id="16">Programming -> Javascript -> AJAX -> ajax nested</option>
<option id="2">History</option>
<option id="6">History -> World history</option>
<option id="9">History -> World history -> Europe</option>
<option id="10">History -> World history -> American</option>
</select>

看起来像: this

我正在考虑两个方案:

  1. 一些具有递归功能的服务和干净的 php 代码,return 具有完整 HTML 结构的变量(select + 选项)和在模板文件中显示该变量。

  2. 一些Laravel方式,我不知道如何实现。

在您的 blade 主模板中,请按照以下步骤操作。在这里,我们首先添加 select 框,然后循环遍历类别。如果 parent 类别有 child,则首先通过调用另一个模板并将 child 数据传递给它来添加 child。

<select name="" id="">     
    @foreach ($categories as $category)
        <option value="{{ $category->id }}">{{ $category->name }}</option>

        @if (count($category->childs) > 0)
            @include('subcategories', ['subcategories' => $category->childs, 'parent' => $category->name])
        @endif

    @endforeach
</select>

现在,我们必须创建 childs 显示模板。根据我的示例,名称应为 subcategories.blade.php。在 child blade 模板中,添加以下内容:

@foreach ($subcategories as $sub)
    <option value="{{ $sub->id }}">{{ $parent}} -> {{ $sub->name }}</option>

    @if (count($sub->childs) > 0)
        @php
            // Creating parents list separated by ->.
            $parents = $parent . '->' . $sub->name;
        @endphp
        @include('subcategories', ['subcategories' => $sub->childs, 'parent' => $parents])
    @endif
@endforeach

在 child 模板中,只要每个 child 都有其他 childs,我们就会一遍又一遍地递归调用 child 模板本身。

而且,这是我机器上的结果:https://ibb.co/ynRB04h