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

Rob*_*rle 1 doctrine symfony1 nested-sets

我目前正在学习symfony1.4,并试图在学说的嵌套集特征中导航,但成效有限.我有一个类别表使用嵌套的行为与mutliple树.我的类别树数据最多可达六个...

Categories:
  columns:
    category_name:
      type: string(40)
  actAs:
    NestedSet:
      hasManyRoots: true
      rootColumnName: parent_id
Run Code Online (Sandbox Code Playgroud)

这些类别是针对产品的,我想要一个页面来过滤类别以到达叶子以显示类别产品,例如显示根,如果选择了根,则显示其子项,然后如果选择了子项显示它的子等,直到你选择一个叶节点. 这是一张可以更好地描述它的图像

我试图建立一个过滤类别的二维数组,传递给视图......没有成功.任何解决方案都会有所帮助,因为我的头很油炸!

非常感谢,

抢.

gre*_*ire 5

改写

重述你的问题:你需要(你的节点的每个祖先和你的节点)和他们的兄弟姐妹.

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

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

这是第三个更简单的改述:你需要的只是你节点的每个祖先的孩子(和披头士的爱情一样).

获取数据

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

$this->ancestors = $currentCategory->getNode()->getAncestors()->getData();
Run Code Online (Sandbox Code Playgroud)

现在让我们构建一个查询,它将为您提供所需的信息.我们假设您的模型被命名为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())
}
Run Code Online (Sandbox Code Playgroud)

如果你不明白这最后是什么,那么你可能需要阅读这篇关于邻接列表模型与嵌套集模型的优秀文章

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

$this->categoryTree = $q->execute(
  array(), 
  Doctrine_Core::HYDRATE_RECORD_HIERARCHY);
Run Code Online (Sandbox Code Playgroud)

O_o等等......最后一个参数是关于什么的?在阅读有关嵌套集的学说文档时,您可能没有听说过它.这是因为它在页面上记录了数据加合器.这真的很糟糕,因为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
  );
Run Code Online (Sandbox Code Playgroud)

并在_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; ?>
Run Code Online (Sandbox Code Playgroud)

我只是写了这个没有测试任何东西,所以它可能从一开始就不能正常工作.只是告诉我你遇到的问题.祝好运!