I think the following implementation can work for you. Define a Model for the tree . You can get away with a just having a TreeNodeModel
->
export class TreeNodeModel{
public Id:number;
public Disabled:boolean;
public Checked:boolean // keeps the state
public Text:string; // optional description or input for description
public Title: string; // title of the node for display
// collection of all the child nodes and their children etc
public Nodes: TreeNodeModel[]=[];
}
So you can further complicate the model depending on your requirement:
Then create a TreeNodeComponent
and as an Input pass it an empty TreeModel or populated one (depending on your requirements):
@component({selector:'app-tree-node',templateUrl:'tree.component.html'})
export class TreeComponent{
constructor(private treeStateService: TreeStateService){}
@Input() Nodes: TreeNodeModel[]=[];
public NodeToggled(node: TreeNodeModel){
// notify any other component you need that node is selected
if(node.Checked){
this.treeStateService.notifyNodeChecked(node);
}
}
}
Then your tree component simply needs to display the checkboxes and any other relevant display/input elements:
<div *ngFor="let node of Model?.Nodes">
<input type="checkbox" [(ngModel)]="node.Checked" [disabled]=node.Disabled>
<label>{{node.Title}}</label>
<!--Display the child checkboxes-->
<app-tree-node [Nodes]="node?.Nodes"></app-tree-node>
</div>
So now you are able to display all your parent nodes and their children. You can further more create a tree.state.service
@Injectable({provideIn:'root'})
export class TreeStateService{
private nodeCheked = new Subject<TreeNodeModel>();
public nodeChecked$ = this.nodeChecked.asObservable();
public notifyNodeChecked(node: TreeNodeModel){
this.nodeChecked.next(node);
}
}
Then in which ever component that you host the tree pass in the nodes and subscribe to the service:
@Component({selector:'app-parent'})
export class ParentComponent implement OnInit{
constructor(private treeStateService: TreeStateService){}
ngOnInit(){
this.treeStateService.nodeChecked$.subscribe((selectedNode)=>{
// do what you need with the node
});
}
}
Please note i did not compile this code. Also as described in the angular site, unsubscribe from non http subscriptions in ngOnDestroy .