【问题标题】:symfony - nestedSet and rendering of parent/child nodessymfony - 嵌套集和父/子节点的渲染
【发布时间】:2011-05-12 09:16:58
【问题描述】:

我使用 Symfony1.4 中的原则 nestedSet 行为创建了一个模型,因为我正在尝试创建一个带有分层页面的基本 cms。

我有几个页面,有父节点和子节点

Parent_1
   Child_1
   Child_2
Parent_2
   Child_3

我的问题是根据导航标题呈现这些项目。 (<ul><li>等)

最简单/最好的方法是什么?

我希望 root 节点具有诸如 /parent_1 之类的 URL 以及后续的子节点,即 parent_1/child_1

谢谢

【问题讨论】:

    标签: symfony1 symfony-1.4


    【解决方案1】:

    我写了一个递归函数,它将从任何节点开始绘制树。指定根节点将绘制整个树。在我的购物车插件中使用,您可以查看完整UI的演示here

    我已经粘贴了下面的函数,但从我的实现中对其进行了修改以使其更清晰。

    <?php
    //Render a nested set.  Recurses for all descendants of that node. Can be used to draw entire tree, when specifying root id.
    //Secondary parameter ($node) is used for performance boost, internally in function.
    public static function display_node($id, $node = null) {
    
        $isRoot = false;
    
        if ($node == null) {
            $node = Doctrine_Core::getTable('YOURNESTEDTABLENAME')->findOneById($id)->getNode();
            if ($node->isRoot()) {
                $isRoot = true;
            }
        }
        $record = $node->getRecord();
    
        if (!$isRoot) {
            echo "<li class='tree_item' id='list_". $record->getId() . "'>"; 
            echo "<div class='listitem' id='listitem_".$record->getId()."'>";
            echo $record->getName();
            echo "<div style='clear:both'></div>";
            echo "</div>";
    
            if ($node->hasChildren()) {
                echo "<ol>";
                foreach ($node->getChildren() as $child) {
                    self::display_node($child->getId(), $child->getNode());
                }
                echo "</ol>";
            }
        }
        else {
            if ($node->hasChildren()) {
                echo "<ol class='sortable'>";
                echo "<li class='tree_item root_item' style='position: relative;' id='list_". $record->getId() . "'>";
                foreach ($node->getChildren() as $child) {
                    self::display_node($child->getId(), $child->getNode());
                }
                echo "</ol>";
            }
        }
    }
    ?>
    

    您还可以根据需要轻松修改代码以添加 URL。 希望这会有所帮助。如果您需要澄清,请告诉我。

    【讨论】:

    • @Jon 谢谢你!这对我来说很有意义。我的根节点是0。我正在尝试使用组件调用此函数,但我有点不确定应该如何使用$categoryid
    • @Jon 目前我有:$categoryid = '1'; $this-&gt;header = TreeTable::display_node($categoryid); 这似乎只显示一个子节点,而不是任何其他的父节点或子节点。任何想法我做错了什么?
    • Category 是我使用 NestedSets 设置的“实体”。在您的情况下,它将类似于 PageID。您可以按照自己的方式查询 NestedSet 模型,我只是使用了 ID,因为它对我的每个类别都是唯一的。
    • 好的,同样的代码是否打开了菜单:cart.samedraw.com 这就是我真正想要的。我有一个嵌套管理模块,只是不像你所拥有的那样是前端导航菜单。
    • 我为你整理了一下代码,可能会更清晰一点。我从等式中删除了“假根”节点。该代码与 cart.samedraw.com 站点不同,但由于很多代码是针对我的实现而修改的。您可以在这里查看所有内容 github.com/jongallant/sfCartPlugin ... 或者特别是在此文件中 github.com/jongallant/sfCartPlugin/blob/master/lib/cart.php
    【解决方案2】:

    我讨厌在模板以外的任何地方回显视图元素,所以这是我的版本。

    //actions:
        public function executeShow(sfWebRequest $request)
        {
          $this->tree = Doctrine::getTable('Model')->getMenuTree();
        }
    
    //lib:
        class ModelTable extends Doctrine_Table
        {
          /**
           * Gets tree element in one query
           */
          public function getMenuTree()
          {
    
            $q = $this->createQuery('g')
              ->orderBy('g.root_id')
              ->addOrderBy('g.lft')
              ->where('g.root_id NOT NULL');
    
            return $q->execute(array(),  Doctrine_Core::HYDRATE_ARRAY_HIERARCHY);
          }
        }
    
    //template:
    
    <?php function echoNode($tree, $parent=null) { ?>
      <ul>
      <?php foreach ($tree as $node): ?>
        <li data-id='<?php echo $node['id'] ?>'>
          <?php echo $node['name'] ?>
          <?php if (count($node['__children']) > 0): ?>
            <?php echo echoNode($node['__children'], $node) ?>
          <?php endif; ?>
        </li>
      <?php endforeach; ?>       
      </ul>
    <?php } ?>
    
    <?php echo echoNode($tree) ?>
    

    现在,如果您需要树的一部分,您可以在一个动作中执行,或者更好的是,为此编写一个单独的模型方法。

    【讨论】:

    • 好的,Doctrine 查询抛出了一个错误,与 where 子句有关。另一个问题是以parent-1 的形式获取父节点的url,然后以parent-1/child-1 的形式获取子节点的url。这可能吗?
    • 好吧,如果你确定所有对象都是某个树的一部分(root_id 不是 NULL),你可以删除 where 子句。将模型迁移到嵌套集时可能会出现这种情况。
    • 是的,我刚刚输入了IS NOT NULL 并且似乎有效。关于路由/URL,有没有简单的方法可以做到这一点?
    • 绝对是我的错。不太明白你关于 url 的问题。我建议你开始一个单独的问题,更好地解释你需要什么。
    • 我问了一个新问题,对 url/路由有更详细的解释:stackoverflow.com/questions/5994668/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 2018-06-27
    • 1970-01-01
    相关资源
    最近更新 更多