parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Ответ

G_Z 07.04.2016 18:34 / 07.04.2016 18:34

Думаю, причина в строчке
$parent_id(^parent_id.int(0))
После выборки поддерева в нём не будет узла с нулевым parent_id, как в случае выборки от корня.
Поэтому нужно ориентироваться на наименьший parent_id.

Если фрагмент дерева выбирается без включения начального узла
…
WHERE t.ancestor_id = $root
AND t.distance > 0
, то parent_id будет равен начальному узлу, так как будут извлечены его потомки.
Тогда достаточно изменения:
^print[$tree]
->
^print[$tree]($root)
Если же начальный узел включается, то мы уже не знаем его parent_id, с которого нужно начинать вывод дерева.
В случае упорядоченного дерева
ORDER BY p.ancestor_id
достаточно взять наименьший parent_id в случае, если оный не передан:
$parent_id(^parent_id.int(0))
->
$parent_id(^parent_id.int(^tree._at[first;key]))
Итого:
CREATE TABLE `_tree` (
	`page_id` INT(10) UNSIGNED NOT NULL,
	`ancestor_id` INT(10) UNSIGNED NOT NULL,
	`distance` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
	PRIMARY KEY (`page_id`, `ancestor_id`, `distance`),
	INDEX `idx_ancestor_id` (`ancestor_id`),
	CONSTRAINT `fk_ancestor_id` FOREIGN KEY (`ancestor_id`) REFERENCES `_tree` (`page_id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

INSERT INTO `_tree` (`page_id`, `ancestor_id`, `distance`)
VALUES
(0, 0, 0),
(1, 0, 1),
(1, 1, 0),
(2, 0, 2),
(2, 1, 1),
(2, 2, 0),
(3, 0, 2),
(3, 1, 1),
(3, 3, 0),
(4, 0, 3),
(4, 1, 2),
(4, 3, 1),
(4, 4, 0),
(5, 0, 4),
(5, 1, 3),
(5, 4, 1),
(5, 5, 0),
(5, 3, 2);

@main[]
$root(3)

^connect[$SQL.connect-string]{
	$tree[^table::sql{
		SELECT t.page_id, p.ancestor_id AS parent_id
		FROM _tree AS t
		JOIN _tree AS p ON (p.page_id = t.page_id AND p.distance = 1)
		WHERE t.ancestor_id = $root
		ORDER BY p.ancestor_id
	}]
}

$tree[^tree.hash[parent_id][
	$.type[table]
	$.distinct(true)
]]

<style>
	#tree div { border: 1px solid gray }
	#tree div div { margin-left: 50px }
</style>

<div id="tree">
	^print[$tree]
</div>


@print[tree;parent_id][locals]
$parent_id(^parent_id.int(^tree._at[first;key]))
$children[$tree.$parent_id]
$result[]

^if($children){
	$result[^children.menu{
		<div>
			<strong>$children.page_id</strong>
			^print[$tree]($children.page_id)
		</div>
	}]
}