【问题标题】:Translate javascript makeTree in Laravel在 Laravel 中翻译 javascript makeTree
【发布时间】:2022-07-07 23:32:36
【问题描述】:

我正在使用 Laravel 8。目前我的项目中有这个函数来构建一个 json 树,但它是客户端,我想在 json 响应 laravel 端点上制作这个树。

 makeTree = (nodes, parentId) => {
    return nodes
      .filter((node) => node.parent_id === parentId)
      .reduce(
        (tree, node) => [
          ...tree,
          {
            ...node,
            children: this.makeTree(nodes, node.id),
          },
        ],
        []
      );
  };

实际上端点像这样返回平面数据:

[{"id":1,"parent_id":null,"value":"Val1"} {"id":2,"parent_id":1,"value":"Val2"} ...]

然后我在makeTree 函数中发送接收到的数组来构建树:

[
  {
    "id":1,
    "parent_id":null,
    "value":"Val1",
    "children":[
      {
        "id":2,
        "parent_id":1,
        "value":"Val2",
        "children":[]
      },
      {
        "id":3,
        "parent_id":1,
        "value":"Val3",
        "children":[]
      },
    ]
  }
    ...
]

这是我的模型:

class MyTree extends Model
{
    protected $table = 'my_tree';
    public $timestamps = true;
    protected $fillable = [
        'parent_id',
        'value',
    ];

    /**
     * A child belongs to a parent.
     *
     * @return MyTree
     */
    public function parent()
    {
        return $this->belongsTo(MyTree::class, 'parent_id');
    }

    /**
     * An Parent has many Children.
     *  *
     * @return MyTree[]
     */
    public function children()
    {
        return $this->hasMany(MyTree::class, 'parent_id');
    }
}

你能帮我用php和laravel关系构建makeTree函数服务器端吗?有一种方法可以使用像 makeTree 这样的递归函数吗?

【问题讨论】:

  • 你的树有多深?
  • @N69S 我的树没有限制,它是一棵无限大的树

标签: php laravel


【解决方案1】:

老实说,我并没有深入研究 javascript sn-p,但我可以在这里分享一些我过去使用过的代码,而且效果很好。实际上,我之前已经找到了一些 sn-p 并为我自己改进了它。目前没有那个确切的链接(如果有的话会更新),但这就是我所拥有的:

在这里你可以使用无限深的树枝。

假设我们遵循 MyTree 模型:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class MyTree extends Model
{
    protected $table = 'my_tree';

    protected $fillable = [
        'id',
        'parent_id',
        'value',
    ];
}

所以我们可以通过查询从 DB 中获取所有 MyTree 项,然后使用 getNestedItems 方法将其转换为这样的树数组:

注意:这里有一些额外的内容,但它不会阻止您获得解决方案。这是排除某些根项目的附加参数:

public function getNestedItems($exclude_parent_id = null): array
{
    $arr = MyTree::select([
        'id',
        'parent_id',
        'value',
    ])
        ->when(isset($exclude_parent_id), function ($query_id) use ($exclude_parent_id) {
            return $query_id->where('id', '!=', $exclude_parent_id);
        })
        ->get()
        ->toArray();

    if (count($arr) > 0) {
        $new = [];
        foreach ($arr as $a) {
            $parent_id = empty($a['parent_id']) ? 0 : $a['parent_id'];
            $new[$parent_id][] = $a;
        }

        $tree = $this->mekeTree($new, $new[0], $exclude_parent_id);

        return [
            'count' => count($arr),
            'tree' => $tree,
        ];
    } else {
        return [
            'count' => 0,
            'tree' => [],
        ];
    }
}

如您所见,我们从 getNestedItems 调用了 ma​​keTree 方法,该方法将递归地创建树“分支”。所以是的,这是一个使用PHP references 的递归函数:

protected function mekeTree(&$list, $parent, $exclude_parent_id): array
{
    $tree = [];
    foreach ($parent as $k => $l) {
        if(isset($list[$l['id']])) {
            if ($l['id'] == $exclude_parent_id) {
                continue;
            }
            $l['children'] = $this->mekeTree($list, $list[$l['id']], $exclude_parent_id);
        }
        $tree[] = $l;
    }

    return $tree;
}

还有 here is a Gist 我刚刚创建的。

享受吧!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-01
    • 2022-10-05
    • 2015-09-04
    • 2020-05-27
    • 2016-12-06
    • 2023-02-23
    • 2021-11-13
    相关资源
    最近更新 更多