Я хотел бы, чтобы метод расчета глубины правильно вычислил глубину, и вместо этого он выполняет расчет в обратном порядке, присваивая первому элементу глубину 2, второму - глубину 1 и третьему - глубину 0, возможно, мне нужно создать новый метод, где он получает RevisionData, а затем просмотрите элемент за элементом. И не рассчитывает по каким-либо причинам глубину больше 2.
<template>
<acc-data-table-v2
:data = "revisionData"
:columns = "columns"
primaryColumn = "id"
treeRowKey = "id"
row-key = "id"
:treeProps = "{children: 'children'}"
:row-class-name = "tableRowClassName"
>
<template v-slot:subflowsRevisionsDescriptionTemplate = "slotProps">
<div>
<div :style = "{ marginLeft: calculateMarginLeft(calculateDepth(slotProps.scope.row)) }">
<div v-if = "slotProps.scope.row.step_id">
{{ slotProps.scope.row.step.description }}
</div>
<div v-if = "!slotProps.scope.row.step_id">
{{ slotProps.scope.row.description }}
</div>
</div>
</div>
</template>
</acc-data-table-v2>
</template>
<script>
export default {
data() {
return {
revisionData: [
{
id: 1, //depth: 0
name: 'Parent 1',
children: [
{
id: 11, //depth: 1
name: 'Child 1.1',
children: [
{
id: 111, //depth: 2
name: 'Grandchild 1.1.1'
},
]
},
{
id: 12, //depth: 1
name: 'Child 1.2'
}
]
},
{
id: 2, //depth:0
name: 'Parent 2',
children: [
{
id: 21, //depth: 1
name: 'Child 2.1'
}
]
}
]
};
},
methods: {
calculateMarginLeft(depth) {
const marginLeft = depth * 12 + 'px';
return marginLeft;
},
calculateDepth(item) {
let depth = 0;
let parent = item;
while (parent.children && parent.children.length > 0) {
depth++;
parent = parent.children[0];
}
return depth;
},
}
};
</script>
@kissu да, и оно там
Извините, если я неправильно понял, но в чем здесь проблема? Кстати, это похоже на то, что вы пытаетесь сделать: vuejs.org/examples/#tree
@kissu проблема в том, что глубина вычисляется неправильно
О, потому что this.calculateDepth(this.revisionData[0].children[0].children[0])
дает 0, находясь на глубине 2? Это имеет смысл, потому что там ничего нет, когда вы находитесь у подножия дерева. Вы всегда можете получить максимум от данного дерева, а затем сделать maximum - currentDepthLevel
, чтобы получить 2 - 0 = 2
за свою 111
ценность. Или вы можете сделать наоборот и попытаться получить родительский элемент , когда-то глубоко вложенный. Таким образом, у 1
будет 0 родителей, а у 111
будет 2 родителя. Нвм это невозможно хаха.
@kissu Я не хочу, чтобы у него был максимум, я хочу, чтобы он был рекурсивным
Оба не связаны между собой. Вычисление максимума может быть итеративным или рекурсивным. Рекурсивные функции не так эффективны в JS, но в данном случае они, по крайней мере, подходят.
Давайте продолжим обсуждение в чате.
Хорошо, вы можете попробовать немного изменить код.
calculateDepth(item) {
let depth = 0;
let parent = item;
// if there is no parent or any parent doesnt have child elemen`
while (parent && parent.children && parent.children.length > 0) {
depth++;
parent = parent.children[0]; // first child
}
return depth;
}
и после этого также рассчитайте оставшийся запас на основе коэффициента глубины
calculateMarginLeft(depth) {
const marginLeft = depth * 12 + 'px';
return marginLeft;
}
Я думаю, это должно сработать!
Что, если у родителя более одного дочернего элемента и, например, второй дочерний элемент имеет более глубокую вложенность, чем первый?
Это довольно простая рекурсивная функция:
Переберите массив и присвойте каждому элементу текущую глубину. Если у элемента есть дочерние элементы, вызовите функцию рекурсивно с увеличенной глубиной. Максимальная глубина — это максимальная глубина любого из дочерних элементов.
function calcDepth(array, d) {
let maxDepth = d;
for (let elem of array) {
elem.depth = d;
if (elem.children?.length)
maxDepth = Math.max(maxDepth, calcDepth(elem.children, d + 1));
}
return maxDepth;
}
let test = [
{
id: "1",
children: [
{
id: "1.1",
children: []
}
]
},
{
id: "2",
children: [
{
id: "2.1",
children: [
{
id: "2.1.1",
children: [
{
id: "2.1.1.1"
}
]
}
]
}
]
}
];
let max = calcDepth(test,0);
console.info(test);
console.info("MaxDepth: ", max);
Это классическая проблема глубины дерева.
Обновите свой код следующим образом:
revisionDataWithDepth
, которое является копией revisionData
с дополнительным полем depth
revisionDataWithDepth
своему :data
calculateMarginLeft(slotProps.scope.row.depth)
<template>
<acc-data-table-v2
:data = "revisionDataWithDepth"
:columns = "columns"
primaryColumn = "id"
treeRowKey = "id"
row-key = "id"
:treeProps = "{children: 'children'}"
:row-class-name = "tableRowClassName"
>
<template v-slot:subflowsRevisionsDescriptionTemplate = "slotProps">
<div>
<div :style = "{ marginLeft: calculateMarginLeft(slotProps.scope.row.depth) }">
<div v-if = "slotProps.scope.row.step_id">
{{ slotProps.scope.row.step.description }}
</div>
<div v-if = "!slotProps.scope.row.step_id">
{{ slotProps.scope.row.description }}
</div>
</div>
</div>
</template>
</acc-data-table-v2>
</template>
<script>
export default {
data() {
return {
revisionData: [
{
id: 1, //depth: 0
name: 'Parent 1',
children: [
{
id: 11, //depth: 1
name: 'Child 1.1',
children: [
{
id: 111, //depth: 2
name: 'Grandchild 1.1.1'
},
]
},
{
id: 12, //depth: 1
name: 'Child 1.2'
}
]
},
{
id: 2, //depth:0
name: 'Parent 2',
children: [
{
id: 21, //depth: 1
name: 'Child 2.1'
}
]
}
]
};
},
computed: {
revisionDataWithDepth: function() {
// create local function that creates a copy of revisionData with depth included
function withDepth(revisions, currentDepth) {
if (!revisions || !revisions.length) {
return [] // or return undefined
}
const revisionsWithDepth = [];
for (const revision of revisions) {
const revWithDepth = { ...revision };
revWithDepth.depth = currentDepth;
revWithDepth.children = withDepth(revision.children, currentDepth + 1);
revisionsWithDepth.push(revWithDepth);
}
return revisionsWithDepth;
}
return withDepth(this.revisionData, 0);
}
}
methods: {
calculateMarginLeft(depth) {
const marginLeft = depth * 12 + 'px';
return marginLeft;
},
}
};
</script>
Совет: вы даже можете использовать однострочник для withDepth
:
function withDepth(revisions, depth) {
return (revisions ?? []).map(revision => ({ ...revision, depth, children: withDepth(revision.children, depth + 1) }))
}
Разве
id: 111
не должно бытьdepth: 2
?