2013-09-12 4 views
0

У меня есть список некоторых элементов, которые связаны друг с другом, как «родитель» и «ребенок», например:базы данных поиска Рекурсивных заполнить список

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

И это продолжается. Я сделал это в базе данных со столбцом «супер», который указывает родительский идентификатор, когда он применим, иначе он равен 0.

У меня нет абсолютно никакой идеи о том, как найти все уровни и применить их к вложенным (один внутри другого) ?) в HTML. Нет предела глубины.

Если какая-либо информация необходима, просто спросите. Я использую PHP 5.5 с Framework CodeIgniter. Pseudocode/algorithm должно быть достаточно для меня, но если вам кажется, PHP-код будет приятным.

+2

Эта ссылка может помочь: http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html – jeff

+0

У меня есть идея о том, как хранить данные, но я не могу думать о том, как ее восстановить позже иерархия, вы знаете? – ranisalt

+0

@jeff: Хорошая ссылка. – mshsayem

ответ

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 для загрузки данных на клиент по мере необходимости. Вы можете добавлять параметры к методам данных и рендеринга для загрузки по определенным ветвям дерева по запросу.

+0

Хм хорошо подумал, динамически загружая использование ajax, кажется приятным. Я попробую это. – ranisalt

+1

@ranisalt отлично, надеюсь, это поможет. Две основные вещи, которые вам нужно добавить для обработки ajax, - это добавление node_parent_id при загрузке дерева. Таким образом, вы можете загрузить определенное поддерево, начиная с того, какой узел нужно загрузить. Вы также не захотите использовать рекурсию по запросам, чтобы она загружала только точный поддерево, на которое нажал пользователь. –

+0

Я на самом деле загружаю динамически то, что пользователь нажимает, а затем я меняю прослушиватель событий щелчка на скрытие или показ переключателя: P таким образом, я загружаю его и сохраняю в документе, а не перезагружаю каждый раз! Мне также не нужно было отображать все дерево. Благодаря! – ranisalt

Смежные вопросы