遍历Doctrine NestedSet结构而不查询

时间:2011-05-14 10:24:18

标签: symfony1 doctrine doctrine-1.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)

1 个答案:

答案 0 :(得分:3)

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

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

这是记录here(除非您选择阅读整个文档,否则很难找到。)

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

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;

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