【问题标题】:Recursively search database to fill a list递归搜索数据库以填充列表
【发布时间】:2013-09-12 03:06:07
【问题描述】:

我有一个列表,其中包含一些相互关联为“父”和“子”的项目,例如:

> Math
-> Trigonometry
--> Angles
--> Sin, cosin and tangent
-> Calculus
(...)
> Biology

这样下去。我在数据库中创建了一个“super”列,当它适用时,它指示父 id,否则为 0。

我完全不知道如何找到所有级别并将它们应用到 HTML 上的嵌套(一个在另一个中?)列表。没有深度限制。

如果需要任何信息,请询问。我正在使用带有 CodeIgniter 框架的 PHP 5.5。伪代码/算法对我来说应该足够了,但如果您愿意,PHP 代码会很好。

【问题讨论】:

标签: php mysql codeigniter search tree


【解决方案1】:

如果您的树将具有无限级别,则您需要使用递归,并且如果您将在树中有很多项目,则需要在构建和渲染树时考虑内存使用情况。

记住这一点,我最近用以下模式解决了一个类似的问题:加载树,然后渲染树。

从 render() 方法开始,您将加载树的所有数据。您将从父节点开始并获取父节点。 get_children() 有一个递归选项来获取孩子的孩子。加载数据后,然后渲染数据。从渲染顶级节点开始,然后递归地渲染子节点和子节点的子节点。

您需要填写这些部分才能真正从数据源中获取数据,但这是一个开始:

<?php

class Tree
{
    var $tree = array();

    function render()
    {
        $this->tree = $this->load();
        $html = ''; // use your favorite templating system to generate the html

        foreach ($this->tree as $parent_node)
        {
            $html .= $this->render_node($parent_node);
        }

        return $html;
    }

    function render_node($parent_node,$recursive=true)
    {
        // use your favorite templating system to generate the html
        $html = '<ul><li>' . $parent_node->name;
        $html .= '<ul>';
        foreach ($parent_node->children as $child)
        {
            $html .= '<li>' . $child->name;
            if ($recursive === true)
            {
                $html .= $this->render_node($child,$recursive);
            }
            $html .= '</li>';
        }
        $html .= '</ul>';        
        $html .= '</li></ul>';

        return $html;
    }

    function load_tree()
    {
        $parents = $this->get_tree_parents();
        foreach ($parents as $parent)
        {
            $parent->children = $this->get_children($parent);
        }

        $this->tree = $parents;
    }

    function get_tree_parents()
    {
        // find all top level nodes in the tree
        return $parent_nodes;
    }

    function get_children($parent,$recursive=true)
    {
        // find all child nodes of the $parent
        $children = array(/*...*/);

        if ($recursive === true)
        {
            foreach ($children as $child)
            {
                $child->children = $this->get_children($child,$recursive);
            }
        }

        return $children;
    }
}

要运行这样的东西,你只需要:

<?php

$tree = new Tree();
echo $tree->render();

您可以根据具体的用例进行各种优化。如果您有一棵巨大的树,您可能需要使用 ajax 仅根据需要在客户端上加载数据。您可以根据要求将参数添加到数据和渲染方法以加载到树的特定分支上。

【讨论】:

  • 嗯,考虑周全,使用 ajax 动态加载似乎不错。我会试试这个。
  • @ranisalt 太好了,我希望它有所帮助。处理 ajax 需要添加的两个主要内容是在加载树时添加 node_parent_id。这样,您可以从需要加载的任何节点开始加载特定的子树。您还希望不对请求使用递归,以便它只会加载用户单击的确切子树。
  • 我实际上是动态加载用户点击的内容,然后我将点击事件侦听器更改为隐藏或显示切换:P 这样,我加载它并保留在文档上,而不是每次都重新加载!我也不需要渲染整棵树。谢谢!
  • @ranisalt 好的,这是有道理的。在我的用例中,我有数以万计的项目,所以最初加载它们并在显示客户端上切换太慢了,所以我不得不走完整的 ajax 路线。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
相关资源
最近更新 更多