I already have a flat data source, meaning I have columns like "content_Id" and "content_Owner" where 0 is root, else is below that content_Id, how can I implement the mat tree component with my data that is already flat??
I found on the web this solution but it fails a little bit, it doesnt take all my data for the tree, I can't see what's wrong
import { Component, OnInit } from '@angular/core';
import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
interface FoodNodeFlat {
name: string;
Id: Number;
parentId: Number;
children?: FoodNodeFlat[];
}
interface ExampleFlatNode {
expandable: boolean;
name: string;
level: number;
}
let TREE_DATA: FoodNodeFlat[] = [
{ name: '1. TITLE', Id: 101, parentId: 0 },
{ name: 'sub', Id: 132, parentId: 129 },
{ name: '5.5.1 sub', Id: 138, parentId: 137 },
{ name: '4.1.1 sub', Id: 144, parentId: 108 },
{ name: '2. TITLE', Id: 102, parentId: 0 },
{ name: '4.1 sub', Id: 108, parentId: 106 },
{ name: '5.6. sub ', Id: 133, parentId: 129 },
{ name: '5.5.2 sub', Id: 139, parentId: 137 },
{ name: '3. TITLE', Id: 103, parentId: 0 },
{ name: '5.6.1 sub', Id: 134, parentId: 129 },
{ name: '5.5.3 sub', Id: 140, parentId: 137 },
{ name: '4. TITLE', Id: 106, parentId: 0 },
{ name: '4.2 sub', Id: 110, parentId: 106 },
{ name: '5.7 sub', Id: 135, parentId: 129 },
{ name: '5. TITLE', Id: 129, parentId: 0 },
{ name: '5.4 sub', Id: 136, parentId: 129 },
{ name: '6. TITLE', Id: 131, parentId: 0 },
{ name: '5.5 sub', Id: 137, parentId: 129 },
{ name: '5.6 sub', Id: 141, parentId: 129 },
{ name: '7. TITLE', Id: 142, parentId: 0 },
{ name: '8. TITLE', Id: 143, parentId: 0 },
{ name: '9. TITLE', Id: 145, parentId: 0 },
{ name: '10. TITLE', Id: 146, parentId: 0 }
];
@Component({
selector: 'app-tree-demo',
templateUrl: './tree-demo.component.html',
styleUrls: ['./tree-demo.component.css']
})
export class TREEDEMOComponent implements OnInit {
private _transformer = (node: FoodNodeFlat, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
};
}
treeControl = new FlatTreeControl<ExampleFlatNode>(
node => node.level, node => node.expandable);
treeFlattener = new MatTreeFlattener(
this._transformer, node => node.level, node => node.expandable, node => node.children);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
constructor() {
//this.dataSource.data = TREE_DATA;
}
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
ngOnInit() {
//this.dataSource.data = TREE_DATA;
this.dataSource.data = this.treeConstruct(TREE_DATA);
}
treeConstruct(treeData) {
let constructedTree = [];
for (let i of treeData) {
let treeObj = i;
let assigned = false;
this.constructTree(constructedTree, treeObj, assigned)
}
return constructedTree;
}
constructTree(constructedTree, treeObj, assigned) {
if (treeObj.parentId == 0) {
treeObj.children = [];
constructedTree.push(treeObj);
return true;
} else if (treeObj.parentId == constructedTree.Id) {
treeObj.children = [];
constructedTree.children.push(treeObj);
return true;
}
else {
if (constructedTree.children != undefined) {
for (let index = 0; index < constructedTree.children.length; index++) {
let constructedObj = constructedTree.children[index];
if (assigned == false) {
assigned = this.constructTree(constructedObj, treeObj, assigned);
}
}
} else {
for (let index = 0; index < constructedTree.length; index++) {
let constructedObj = constructedTree[index];
if (assigned == false) {
assigned = this.constructTree(constructedObj, treeObj, assigned);
}
}
}
return false;
}
}
}
and my HTML as below
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<!-- use a disabled button to provide padding for tree leaf -->
<button mat-icon-button disabled></button>
{{node.name}}
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding>
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
{{node.name}}
</mat-tree-node>
</mat-tree>
