laravel 递归

tech2022-09-02  120

laravel 递归

In this tutorial, we’ll go through the process of implementing recursive partials in Laravel’s Blade templating engine by means of the @each command. This will allow us to render data structures with an arbitrary number of nested children without needing to know the maximum depth of the array.

在本教程中,我们将通过@each命令介绍在Laravel的Blade模板引擎中实现递归局部函数的过程。 这将使我们能够渲染具有任意数量的嵌套子级的数据结构,而无需知道数组的最大深度。

数据 (The Data)

The data I’m talking about is data like folder structures which can go deep into many levels. For our case, let’s imagine we’re dealing with a predefined data set of “Projects” in a todo application like Todoist. Feel free to grab the sample data from this gist or the code embed below:

我要说的数据是文件夹结构之类的数据,它可以深入到很多层次。 对于我们的情况,让我们想象一下,正在像Todoist这样的todo应用程序中处理预定义的“项目”数据集。 请随意从此要点或下面嵌入的代码中获取示例数据:

$a = array( 0 => array( 'indent' => 1, 'name' => 'Inbox', 'color' => '#dddddd', 'is_deleted' => 0, 'collapsed' => 0, 'inbox_project' => true, 'archived_date' => null, 'item_order' => 0, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 138837507, 'children' => array(), 'parent' => 'root', ), 1 => array( 'indent' => 1, 'name' => 'Personal', 'color' => '#fc603c', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 1, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 138837508, 'children' => array(), 'parent' => 'root', ), 2 => array( 'indent' => 1, 'name' => 'Work', 'color' => '#a8c9e5', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 2, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 138837509, 'children' => array( 0 => array( 'indent' => 2, 'name' => 'Work indent 1-1', 'color' => '#a8c9e5', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 3, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 139576614, 'children' => array( 0 => array( 'indent' => 3, 'name' => 'Work indent 1-2', 'color' => '#dddddd', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 4, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 139576626, 'children' => array(), 'parent' => 139576614, ), 1 => array( 'indent' => 3, 'name' => 'Work indent 1-2 2nd', 'color' => '#dddddd', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 5, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 139576629, 'children' => array(), 'parent' => 139576614, ), ), 'parent' => 138837509, ), 1 => array( 'indent' => 2, 'name' => 'Work indent 2-1', 'color' => '#a8c9e5', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 6, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 139576622, 'children' => array( 0 => array( 'indent' => 3, 'name' => 'Work indent 2-2', 'color' => '#dddddd', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 7, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 139576636, 'children' => array(), 'parent' => 139576622, ), ), 'parent' => 138837509, ), 2 => array( 'indent' => 2, 'name' => 'Work indent 3-1', 'color' => '#dddddd', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 8, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 139576646, 'children' => array(), 'parent' => 138837509, ), ), 'parent' => 'root', ), 3 => array( 'indent' => 1, 'name' => 'Errands', 'color' => '#74e8d4', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 9, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 138837510, 'children' => array(), 'parent' => 'root', ), 4 => array( 'indent' => 1, 'name' => 'Shopping', 'color' => '#dddddd', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 10, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 138837511, 'children' => array(), 'parent' => 'root', ), 5 => array( 'indent' => 1, 'name' => 'Movies to watch', 'color' => '#e3a8e5', 'is_deleted' => 0, 'collapsed' => 0, 'archived_date' => null, 'item_order' => 11, 'is_archived' => 0, 'archived_timestamp' => 0, 'user_id' => 3840103, 'id' => 138837512, 'children' => array(), 'parent' => 'root', ), );

普通的旧PHP (Plain old PHP)

When using plain old PHP for outputting such data, one would probably use a method like this one:

当使用普通的旧PHP输出此类数据时,可能会使用如下方法:

public function output($projects) { $string = "<ul>"; foreach ($projects as $i => $project) { $string .= "<li>"; $string .= $project['name']; if (count($project['children'])) { $string .= $this->output($project['children']); } $string .= "</li>"; } $string .= "</ul>"; return $string; }

Ew. It works, but it’s highly inflexible and it mixes presentation with logic. Let’s not do this.

真是的 它可以工作,但是非常不灵活,并且将表示与逻辑结合在一起。 让我们不要这样做。

刀锋之刃 (Blade Foreach)

With Blade, things become a little simpler. We can use the foreach construct to help us out.

使用Blade,事情变得简单一些。 我们可以使用foreach构造来帮助我们。

@if (count($projects) > 0) <ul> @foreach ($projects as $project) @include('partials.project', $project) @endforeach </ul> @else @include('partials.projects-none') @endif

As Blade doesn’t really support defining functions, thus not letting us call them recursively like the output function above, we need to define partials and have them call themselves:

由于Blade并不真正支持定义函数,因此不像上面的output函数那样让我们递归地调用它们,因此我们需要定义局部函数并使它们自己调用:

partials/project.blade.php

partials/project.blade.php

<li>{{ $project['name'] }}</li> @if (count($project['children']) > 0) <ul> @foreach($project['children'] as $project) @include('partials.project', $project) @endforeach </ul> @endif

partials/projects-none.blade.php

partials/projects-none.blade.php

You have no projects!

But… so much code for something so rudimentary. Is there no way to shorten this even further?

但是……那么多的代码就太基本了。 有没有办法进一步缩短?

刀片@each (Blade @each)

There is an un(der)documented feature of Laravel Blade that’ll help us decimate the LoC count in our template files, making the lives of both our devs and designers much easier. The feature is @each and is used thusly:

Laravel Blade有一个未公开的功能,可以帮助我们减少模板文件中的LoC数量,从而使开发人员和设计师的生活变得更加轻松。 该功能是@each ,因此可以使用:

@each('viewfile-to-render', $data, 'variablename','optional-empty-viewfile')

The first argument is the template to render. This will usually be a partial, like our project.blade.php. The second one is the iterable dataset, in our case $projects. Third is the variable name the elements will use when being iterated upon. For example, in foreach ($data as $element), this argument would be element (without the $). The fourth argument is an optional one – it’s the name of the template file which should be rendered when the second argument ($data) is empty, i.e. has nothing to iterate over. If we apply all this to our case, we can replace this entire block:

第一个参数是要渲染的模板。 这通常是部分的,例如我们的project.blade.php 。 第二个是可迭代的数据集,在本例中$projects 。 第三是元素被迭代时将使用的变量名。 例如,在foreach ($data as $element) ,此参数将为element (不带$ )。 第四个参数是一个可选参数–它是模板文件的名称,当第二个参数( $data )为空(即没有要迭代的内容)时,应呈现该模板文件。 如果将所有这些应用于我们的案例,则可以替换整个块:

@if (count($projects) > 0) <ul> @foreach ($projects as $project) @include('partials.project', $project) @endforeach </ul> @else @include('partials.projects-none') @endif

with

@each('partials.project', $projects, 'project', 'partials.projects-none')

结论 (Conclusion)

In this short tutorial, we saw how we can leverage an underdocumented feature of Laravel Blade to drastically reduce the number of lines in our template code. By using @each and relying on partials and their ability to recursively call themselves, we have an amazing arsenal of tools at our disposal for outputting all manners of data – it’s just a matter of putting the building blocks in the right order.

在这个简短的教程中,我们看到了如何利用Laravel Blade的文档不足的功能来大大减少模板代码中的行数。 通过使用@each并依靠@each及其递归调用自身的能力,我们可以使用大量惊人的工具来输出各种方式的数据–只需按正确的顺序构建构建块即可。

You can use this approach of partials recursion to echo out directory trees, content management categories, employee directories, and much, much more.

您可以使用这种部分递归的方法来回显目录树,内容管理类别,员工目录等等。

Did you know about @each? Do you know of any other hidden gems? Let us know in the comments!

您知道@each吗? 您还知道其他隐藏的宝石吗? 让我们在评论中知道!

翻译自: https://www.sitepoint.com/laravel-blade-recursive-partials/

laravel 递归

最新回复(0)