php – 将嵌套集合模型嵌入到隐藏的“封闭”子树中

前端之家收集整理的这篇文章主要介绍了php – 将嵌套集合模型嵌入到隐藏的“封闭”子树中前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
基于 Getting a modified preorder tree traversal model (nested set) into a <ul>

其中一个答案给出了正确的代码显示完整的树.我需要的是总是显示一级(深度= 0)和兄弟姐妹的活动列表项.目标是在用户选择更多列表项目的父项的列表项时展开树的可见部分.

所以,如果我得到这个列表:

1. item
2. item
  2.1. item
  2.2. item
    2.2.1. item
    2.2.2. item
    2.2.3. item
  2.3. item
  2.4. item
    2.4.1. item
    2.4.2. item
3. item
4. item
  4.1. item
  4.2. item
    4.2.1. item
    4.2.2. item
5. item

如果当前列表项为“2.”,列表应如下所示:

1. item
2. item // this needs class .selected
  2.1. item
  2.2. item
  2.3. item
  2.4. item
3. item
4. item
5. item

如果当前列表项是“2.2”,则列表应如下所示:

1. item
2. item // this needs class .selected
  2.1. item
  2.2. item // this needs class .selected
    2.2.1. item
    2.2.2. item
    2.2.3. item
  2.3. item
  2.4. item
3. item
4. item
5. item

下面是一个示例代码,对我来说显示完整的树很好.我还添加了需要解决我的问题的lft / rgt / current.

<?PHP
function MyRenderTree ( $tree = array(array('name'=>'','depth'=>'','lft'=>'','rgt'=>'')),$current=false){

   $current_depth = 0;
   $counter = 0;

   $result = '<ul>';

   foreach($tree as $node){
       $node_depth = $node['depth'];
       $node_name = $node['name'];
       $node_id = $node['category_id'];

       if($node_depth == $current_depth){
           if($counter > 0) $result .= '</li>';
       }
       elseif($node_depth > $current_depth){
           $result .= '<ul>';
           $current_depth = $current_depth + ($node_depth - $current_depth);
       }
       elseif($node_depth < $current_depth){
           $result .= str_repeat('</li></ul>',$current_depth - $node_depth).'</li>';
           $current_depth = $current_depth - ($current_depth - $node_depth);
       }
       $result .= '<li id="c'.$node_id.'"';
       $result .= $node_depth < 2 ?' class="open"':'';
       $result .= '><a href="#">'.$node_name.'</a>';
       ++$counter;
   }
   $result .= str_repeat('</li></ul>',$node_depth).'</li>';

   $result .= '</ul>';

   return $result;
}

// "$current" may contain category_id,lft,rgt for active list item
print MyRenderTree($categories,$current);
?>
当您已经设法排序序列时,为什么不根据需要输出

由于某些叶需要关闭,所以迭代器应该能够跳过非选定节点的子节点.

这样做导致我想到解决终止输出树(output = parsing)的问题.如果序列中的最后一个有效节点的深度高于0,该怎么办?我附加了一个NULL终结符.因此,在循环完成之前,仍然可以关闭开放级别.

此外,迭代器重载节点以提供常见的方法,如与当前选择的元素进行比较.

MyRenderTree函数(Demo/Full code)

编辑:Demo键盘有问题,这里是源代码Gist
Getting nested set model into a but hiding “closed” subtrees

function MyRenderTree($tree = array(array('name'=>'',$current=false)
{
    $sequence = new SequenceTreeIterator($tree);

    echo '<ul>';
    $hasChildren = FALSE;
    foreach($sequence as $node)
    {
        if ($close = $sequence->getCloseLevels())
        {
            echo str_repeat('</ul></li>',$close);
            $hasChildren = FALSE;
        }
        if (!$node && $hasChildren)
        {
            echo '</li>',"\n";
        }
        if (!$node) break; # terminator

        $hasChildren = $node->hasChildren();
        $isSelected = $node->isSupersetOf($current);

        $classes = array();
        $isSelected && ($classes[] = 'selected') && $hasChildren && $classes[] = 'open';
        $node->isSame($current) && $classes[] = 'current';

        printf('<li class="%s">%s',implode(' ',$classes),$node['name']);

        if ($hasChildren)
            if ($isSelected)
                echo '<ul>';
            else
                $sequence->skipChildren()
            ;
        else
            echo '</li>'
        ;
    }
    echo '</ul>';
}

这可以在一个单一的foreach和一些变量中解决,但是我认为可重用,基于SPL Iterators的实现更好.

猜你在找的PHP相关文章