【问题标题】:CakePHP: Duplicating/Deep Copying a Tree Structure Easily?CakePHP:轻松复制/深度复制树结构?
【发布时间】:2010-07-22 03:30:53
【问题描述】:

我想知道是否有一种简单的方法来制作一个树结构的副本,该树结构由一个具有作为树的 parent_id 的模型组成?

我在想递归遍历给定的树,删除所有 id 和 lft,rght 字段应该很容易;但是,当我添加新字段时 parent_id 不会正确匹配。我想编写自己的函数来处理这个应该很容易,但我只是想知道是否已经有东西可以处理这个?

谢谢!!

【问题讨论】:

  • 我会在早上用例子回复你!这里是午夜。

标签: cakephp model tree orm


【解决方案1】:

首先,我使用了多树行为 (http://bakery.cakephp.org/articles/view/multitree-behavior),因为它允许在一个表中管理多棵树。

我的示例可能有点复杂,并且与特定于应用程序的代码混淆了,但我相信您可以选择自己的方式!

几乎你对树所做的任何事情都需要一个递归的“tree-walker”。我写了一个带有子任务等的任务管理器,这是我用来遍历树的方法的一个示例:

function _walkTasksTree($nodes, $model='Task')
{
    foreach($nodes as $node)
    {
        $task = $node[$model];
        $id = $task['id'];
        $title = $task['name'];
        $level = $task['level'];

        $children = $this->_walkTasksTree($node['children'],$model);

        if(empty($children))
        {
            $data[$id] = array('level'=>$level,'title'=>$title);
        }
        else
        {
            $data[$id] = array('level'=>$level,'title'=>$title,'children' => $children);
        }
    }
    $data = (isset($data))?$data:array();
    return $data;
}

我的应用程序有一个常见任务的“存储库”,可以将其克隆到项目中。基本模型是 ProjectTask [1:1] ProjectTaskDescriptor - 保存数据的描述符,以及保存树位置的任务。我使用这种方法来遍历和克隆树和/或分支

function _saveTaskTree($subTasks,$parent_id,$root_id,$projId,$exclude=null)
{
    foreach($subTasks as $node)
    {
        if(@$exclude!=$node['Task']['id'])
        {
            $node['Task']['id'] = null;
            $node['Task']['root_id'] = $root_id;
            $node['Task']['parent_id'] = $parent_id;
            $node['Task']['project_id'] = $projId;
            $this->ProjectTask->create();
            $saved = $this->ProjectTask->save($node['Task']);
            $this->ProjectTaskDescriptor->create();
            $PTD = $node['TaskDescriptor'];
            $PTD['project_task_id'] = $this->ProjectTask->id;
            $this->ProjectTaskDescriptor->save($PTD);
        }
        else
        {
            $saved = true; //skip the first one - we've already done it.
        }
        if($saved)
        {
            if(@$node['children'])
                $children = $this->_saveTaskTree($node['children'],$this->ProjectTask->id,$root_id,$projId);
        }
    }
}

这是一个非常实际的过程,就未来对代码的理解和维护而言,值得充分了解正在发生的事情。

【讨论】:

  • 啊啊啊,我明白了!是的,这是有道理的,我脑子里有同样的概念!我希望它已经自动化了。谢谢你的例子!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 2013-04-12
相关资源
最近更新 更多