laravel刀片模板打印递归树

时间:2018-06-08 06:24:30

标签: php laravel

tree.blade.php

<ul>

@foreach($places as $p)
    <li>
     <a href="">{{ $p->name }}</a>

    @if($p->children->count())

          @include ('tree', ['places' => $p->children]) //recursion
    @endif
    </li>
@endforeach

</ul>

我的数据库中有2行,所以2是子节点1,问题是当打印第一个树时,它返回到第二个迭代,但第二个迭代是第一个迭代,所以它不应该再次打印,它创建了重复,我应该如何在我的刀片模板中防止这种情况

更新

控制器方法:

public function index()
{
    $data = [];
    $data['places'] = Place::with(['children', 'parent'])->get();

    return view('places/index', $data);
}

1 个答案:

答案 0 :(得分:1)

此时您有几个选项。

1)让Eloquent做繁重的工作

对于小/低流量应用程序,我会说这种方法很好但不会过于高效,因为它会逐个加载每个关系,但是,它应该会给你想要的结果:

$data['places'] = Place::whereNull('parent_id')->with('children')->get();

检查parent_id正在null只会获得根元素。

2)构建树

另一个更高效(DB-wise)的选项是加载所有类别并在控制器中构建树:

$allPlaces = Place::all();

function getChildren($places, $place)
{
    $children = $places->where('parent_id', $place->id)->all()
        ->map(function ($child) use ($places) {
            return getChildren($places, $child);
        });

    $place->setRelation('children', $children);

    return $place;
}

$data['places'] = $allPlaces
    ->filter(function ($place) {
        return is_null($place->parent_id);
    })
    ->map(function ($place) use ($allPlaces) {
        return getChildren($allPlaces, $place);
    });

3)使用嵌套集

此时可能有点过分杀人,但值得一看https://github.com/lazychaser/laravel-nestedset