我有一个带有作为树的类别模型的cakephp应用程序。我通过csv文件导入了~100个类别。
我希望能够按名称快速重新排序所有类别,以便正确排序我的索引视图。
我尝试了reorder
method from the Tree behavior:
$this->Category->reorder(array(
'id' => null,
'field' => 'Category.name',
'order' => 'ASC'
));
但它没有做任何事情。我在这里错过了什么吗?
谢谢:)
答案 0 :(得分:4)
我刚刚对此进行了研究并得出结论,不可能在generatetreelist()
方法中对结果进行排序 - 至少没有简单的方法,如果没有循环并手动移动每个节点。解决这个问题的最好方法是使用普通的find方法,将第一个参数作为'threaded',然后就像任何查询一样应用SQL排序。我的分类模型中有这个方法:
public function getThreaded($conditions = array()) {
return $this->find('threaded', array(
'order' => 'Category.name ASC',
'contain' => false
));
}
这会返回一个按字母排序的所有父类别的数组,其中'children'键包含该类别中所有子类的另一个数组,也按字母顺序排列!我使用contain => false
来减少返回的数据(thread返回有关每个节点的父节点的数据,我们不需要知道),如果需要,可以改变它以包含额外的数据。
我知道这与generatetreelist()
不是100%相同,但是当你控制输出时,它肯定更整洁,更灵活。如果你真的需要模仿generatetreelist()
的行为,你可以像这样从上面循环遍历数组:
$treeArray = array();
foreach($category as $parent) {
$treeArray[] = $parent['Category']['name'];
if(!empty($parent['children']) {
foreach($parent['children'] as $childCategory) {
$treeArray[] = ' - '.$childCategory['Category']['name'];
}
}
}
希望这有帮助。
答案 1 :(得分:4)
只是提醒一下:树行为中的reorder()
方法仅修改MPTT logic后面的树的左和右字段(是此行为使用的树的类型)。它不会使该模型中的所有find()
神奇地传递您的reorder()
方法定义的顺序。您仍然需要在order
选项中传递find()
参数才能实际使用更新后的左右值。
假设您正在使用TreeBehavior使用的默认列名:lft
用于左侧字段,rght
用于右侧字段。运行一次问题中给出的reorder()
方法后,要将模型中的有序数据传递给View,您可以使用以下内容:
$this->Category->find('all', array(
'order' => array(
'Category.lft' => 'ASC'
)
));
当然,如果您想使用find
之外的其他内容,请替换'all'
类型。
按Category.lft
排序实际上会显示您从左到右进行深度优先搜索所获得的顺序 - 不是数据库定义的任意顺序,如果您没有{{1 }}参数,或者如果您在order
选项中使用了一个简单的'order' => 'Category.name'
,它将忽略树结构。
P.S。:我知道这个问题是2年了,但是由于没有其他人解释find
实际的作用,我觉得这很有用。
答案 2 :(得分:1)
如果您使用TreeLi助手将generateTreeList的结果转换为UL / LI列表,则可以使用jQuery插件TinySort对树进行排序(http://tinysort.sjeiti.com/)。