2

我通常像这样获取 NestedSet 树:

class ModelTable extends Doctrine_Table
{
  /**
   * Gets tree elements in one query
   */
  public function getMenuTree()
  {
    $q = $this->createQuery('p')
      ->orderBy('p.root_id')
      ->addOrderBy('p.lft');

    $tree = $q->execute(array(),  Doctrine_Core::HYDRATE_RECORD_HIERARCHY);      

    return $tree;
  }
}

所以我实际上可以在只使用一个查询数据库的同时显示整棵树..直到我尝试遍历树。例如,如果您在这样的节点上调用方法:

$node->getNode()->getAncestors()

Doctrine 将为此建立一个全新的查询(查看 Doctrine_Node_NestedSet::getAncestors())。其他遍历方法如 getChildren() 也使用 DQL。但这有点低效,不是吗?一旦我获取了整棵树,我就不想再查询数据库了。

也许有人写了一个驱动程序来以正确的方式做到这一点?(无 DQL)

4

1 回答 1

3

如果您只想获取孩子(这是最有可能的,为什么需要getAncestors()在树上迭代?),您还可以保留您向我们展示的代码作为示例,并执行以下操作:

foreach ($categories->getFirst()->get('__children') as $child) {
    // ...
}

在此处进行了记录(除非您选择阅读整个文档,否则很难找到)。

我曾经在只有一个查询的整棵树上使用递归代码。

1015 lib % ack --type="php" "_node"                                                                                                                                                          2011-05-15 14:26:22 greg pts/1
vendor/doctrine/Doctrine/Record.php
94:    protected $_node;
814:        unset($vars['_node']);
2403:        if ( ! isset($this->_node)) {
2404:            $this->_node = Doctrine_Node::factory($this,
2410:        return $this->_node;
liche ~/source/symfony/1.4/lib/plugins/sfDoctrinePlugin/lib

_node 似乎只是getNode()自己设置的,我不知道你是否可以像任何其他领域一样水合它,也不知道你会如何做到这一点。

我认为这getNode()应该只用于树上的修改。如果要显示从根开始的路径,则应使用递归方法来显示树,并使用包含父路径的参数。如果还有其他需要树功能的东西,请告诉我们...

更新

我想我最终得到了它。你想显示一个树形菜单和一个面包屑,并且你想在面包屑中重用菜单的数据,不是吗?要显示你的面包屑,你必须在 $tree 上递归,并且当且仅当它是当前页面的祖先时才显示一个节点。并且有一种方法:isAncestorOf()。所以“所有你需要做的”是一个模板,它做这样的事情:

//module/templates/_breadcrumbElement.php
foreach ($node->get('__children') as $child) :
  if ($child->isAncestorOf($pageNode)):
     echo link_to($child->getName(), $child->getUrl());
     include_partial('module/breadcrumbElement', array('node' => $child, 'pageNode' => $pageNode));
  endif;
endforeach;

喂它你的树根,你会没事的。希望。

于 2011-05-15T10:24:12.193 回答