Dan Rullo
Dan Rullo

Reputation: 343

Angular Material Tree - Different parent/child types

Is there a way to utilize a material tree to represent parent/child data structures where the child has a separate data shape than the parent? My experience with this component seems to indicate that the data structure needs to be a recursion of the same type. However, I would like to use it to represent structures such as Orders (parent) with Order Items (children). This does not seem to be a supported use case. Is that correct?

I've been using Angular since the v2 rollout and I've been using Angular Material since inception. In my opinion, the Tree component seems to be the most cumbersome component with the most difficult to sample code.

Upvotes: 16

Views: 4751

Answers (3)

hner
hner

Reputation: 1

Just came across the same question and since there is no example available I came up with the following solution.

/**
 * Any class that implements toString is now usable inside a tree
 */
export interface IString {
    toString : () => string;
}

/**
 * Node for to-do item
 */
export interface Node {
    children? : Node[];
    item : IString;
}

/** Flat to-do item node with expandable and level information */
export interface FlatNode {
    item : IString;
    level : number;
    expandable : boolean;
}

See here for the Stackblitz: https://stackblitz.com/edit/angular-rwur5a

Upvotes: 0

cabay
cabay

Reputation: 41

I had the same issue, the solution I chose was to make a flatten structure just for tree component. Structure have all the fields from parent and child (if model is used on parent, child fields remain empty and opposite on child node). Seems to work just fine.

From:

export interface ParentModel{
  id: number;
  name: string;    
  child: ChildModel[];    
}

export interface ChildModel{
  id: number;
  symbolName: string;    
  description: string;    
}

to:

export interface TreeModel {
  id: number;
  name: string; 
  symbolName: string;
  description: string;

}

Upvotes: 2

IanOx
IanOx

Reputation: 31

Came across a similar problem at work late on Friday, wasn't happy with the result so mocked up a stackblitz that might meet your needs. @Jaikumar's link was helpful - https://material.angular.io/cdk/tree/api#NestedTreeControl.

See this modified stackblitz - https://stackblitz.com/angular/lneeokqoxvm based on the matTree example for a working example.

The key, apart from modifying the interface to fit a loose datastructure was in the NestTreeControl the function at the end appears to be the property/function getChildren.

interface FoodNode {
  name: string;
  children?: FoodNode[]; 
}
...
new NestedTreeControl<FoodNode>(node => node.children)

modified to:

interface FoodNode {
  name: string;
  children?: FoodNode[];
  subChildren?: FoodNode[]; 
}

...

new NestedTreeControl<FoodNode>(node => {
      return (node.children) ? node.children : node.subChildren;
});

The hasChild function at the end of the class has to allow for the added complexity as well:

 hasChild (_: number, node: FoodNode): boolean {
   return (node.subChildren) ? 
    !!node.subChildren && node.subChildren.length > 0 : 
    !!node.children && node.children.length > 0;
  }

The double bang !! made me find this reference - https://medium.com/better-programming/javascript-bang-bang-i-shot-you-down-use-of-double-bangs-in-javascript-7c9d94446054

Hope you find this helpful even though you asked the question months ago.

Upvotes: 1

Related Questions