我目前正在学习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
我正在尝试构建过滤类别的二维数组,以传递给视图......但没有成功。任何解决方案都会有所帮助,因为我的头被炸了!
非常感谢,抢劫。
答案 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; ?>
我只是在没有测试任何东西的情况下编写了这个,所以它可能从一开始就无法正常工作。请告诉我你遇到的问题。祝你好运!