symfony1.4嵌套设置通过级别导航

时间:2011-10-11 17:53:53

标签: symfony1 doctrine nested-sets

我目前正在学习symfony1.4,并试图绕过学说的嵌套集功能,但成功有限。我有一个类别表使用嵌套的行为与mutliple树。我的类别树数据最多可以达到六个......

Categories:
  columns:
    category_name:
      type: string(40)
  actAs:
    NestedSet:
      hasManyRoots: true
      rootColumnName: parent_id

这些类别适用于产品,我想要一个页面来过滤类别以达到一个叶子,以便显示该类别产品,例如显示根,如果选择了根,则显示其子项,然后如果选择子项,则显示其子项等,直到选择叶节点为止。 here's an image which may describe it better

我正在尝试构建过滤类别的二维数组,以传递给视图......但没有成功。任何解决方案都会有所帮助,因为我的头被炸了!

非常感谢,

抢劫。

1 个答案:

答案 0 :(得分:5)

改写

修改你的问题:你需要(节点的每个祖先和你的节点)和他们的兄弟姐妹。

其他改述:你需要你的节点的每个祖先以及他们所有的孩子(但不是他们所有的后代)

并且不要认为你应该将hasManyRoots设置为true,除非你有几家商店。现在让我们假设你有一个根,你可以命名为'shop'

这是第三个更简单的改述:你所需要的只是你节点的每个祖先的孩子(而且,披头士乐队的爱情)。

获取数据

将祖先作为一个数组(请参阅上一个§中的原因)很简单:

$this->ancestors = $currentCategory->getNode()->getAncestors()->getData();

现在让我们构建一个可以满足您需求的查询。让我们假设你的模型被命名为Category,而不是Categories(它确实应该)。

$q = CategoryTable::getInstance()->createQuery('c');
foreach ($this->ancestors as $ancestor)
{
    // should work thanks to AND priority over OR
    $q->orWhere('c.level = ?' $ancestor->getLevel() + 1)
     ->andWhere('c.lft > ?' $ancestor->getLeftValue())
     ->andWhere('c.rgt < ?' $ancestor->getRightValue())
}

如果您不明白最后的事情,那么您可能需要阅读this excellent article about adjacency list model vs nested set model

好了,现在你有了查询,让我们获取结果:

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

O_o等等......最后一个参数是关于什么的?在阅读有关嵌套集的学说文档时,您可能没有听说过它。那是因为它记录在the page about data hydrators上。这真的很糟糕,因为HYDRATE_RECORD_HIERARCHY在使用嵌套集时非常有趣。现在,您在$ categoryTree中拥有所需的一切作为层次结构。无论您的树有多深,只需要2个请求!我猜一个人可以在一个请求中写出来,但我不知道如何。

注意:还有Doctrine_Core::HYDRATE_ARRAY_HIERARCHY,它水合成分层数组,速度更快。如果您不需要调用提供不属于您的对象的东西的方法,或者在运行时计算的方法,则可以使用它。您只需在模板中使用数组而不是对象表示法(例如$categoryTree['children']

显示数据

现在,在您的_menu.php模板中,您可以执行以下操作:

<?php
array_shift($ancestors);
include_partial('level', array(
  'children'  => $categoryTree->get('__children'),
  'ancestors' => $ancestors
  );

_level.php

<ul>
<?php $selectedChild = array_shift($ancestors);
foreach ($children as $child): 
  if ($isSelected = ($child->getId() == $selectedChild->getId())):
    $grandChildren = $child->get('__children');
  endif; ?>
  <li<?php if ($isSelected):?> class="selected"<?php endif?>>
     <?php echo $child->getName() ?>
  </li>
<?php endforeach ?>:
</ul>
<?php if (count($ancestors)):
    // RecursiviRecurRecuRecursiRRecursivityecursivityvityrsivitysivityty
    include_partial('level', array(
      'children'  => $grandChildren,
      'ancestors' => $ancestors
      );
endif; ?>

我只是在没有测试任何东西的情况下编写了这个,所以它可能从一开始就无法正常工作。请告诉我你遇到的问题。祝你好运!