Closed elham-sedighi closed 5 years ago
since tree fills data for children of a node after index of its parent node (in this.data), so when you want to remove or collapse children of a node:
(this.data.splice(index + 1, node.childcount);//children.length)
you just have to count all indexes in data from index of node to reach a node with level equal to the level of the node you wanted to collapse. that count would be used like :
(this.data.splice(index + 1, counter);//children.length)
checkboxes for tree created dynamically wont work fine still. when collapsing a whole root node it changes its check state randomly. can somebody help me with this? check box states for tree created dynamically ....
If you want checkboxes for a tree with dynamic data, you should map a boolean to your data source when fetching it, and use that boolean for the checkbox state. Just invert that boolean on checkbox click.
If you create a stackblitz from your code I can edit it in for you.
stackblitz
https://stackblitz.com/edit/angular-buzxpd
but it cant get http responses in stackblitz, I put my component there anyway. it has checkbox checking problem and collapse and expand sign problem cause i had to remove all nodes expanded under a node (my tree has 4 level).
Better to add some mockup-data, kind of hard to add it when it is not running. I created a custom stackblitz which maps in booleans for the checkboxes, as well as a separate boolean for the expand (so the tree-control is not really used - you still have to add it though). This is done on OnInit, in your case you can map it in after you have fetched the data from server, before you connect it to the treedatasource. Now it remembers the state of expand for children as well as the checkboxes.
https://stackblitz.com/edit/nested-tree-with-checkbox-custom-expand
Please re-open your issue following the issue template provided, including a description of the issue you are seeing, the current behavior, the expected behavior, and a reproduction in Stackblitz
Did anyone fix the issue?
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.
Hi I'm using mat-tree material angular with checkboxes and dynamic data which comes from a http call service. I have two problems now: 1- all root nodes of tree are checked at the beginning! and select and deselect nodes and parent nodes does not work correctly 2- toggling parent nodes does not work fine either because there may be more that one level deeper in a parent node (which I,m trying to collapse) but only first level will be collapsed according to the count of its child. what is the solution? I even used a recursive function to handle that but it's not working fine too. I would be grateful to help me with. here are my codes: view: `<mat-tree [dataSource]="dataSource" [treeControl]="treeControl" dir="rtl"> <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding>
<mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding> <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.filename">
my component:
import { CollectionViewer, SelectionChange, SelectionModel } from '@angular/cdk/collections'; import { FlatTreeControl } from '@angular/cdk/tree'; import { Component, Injectable } from '@angular/core'; import { Service } from '../service/callajaxandhttp/service.component'; import { BehaviorSubject, Observable, merge } from 'rxjs'; import { map } from 'rxjs/operators';export class DynamicFlatNode { constructor( public Title: string, public id: string, public PID: number, public Type: string, public s: string, public haschildren: boolean, public level: number = 1, public expandable: boolean = false, public isLoading: boolean = false, public childcount: number = 0, public children: DynamicFlatNode[] = [] ) { } }
@Injectable() export class DynamicDatabase { dfns: DynamicFlatNode[]; Tempchilddfns: DynamicFlatNode[];
public getData(url: string, ptitle: string, parentnode: string): Promise {
ptitle = ptitle != '' ? '?ptitle=' + ptitle : '';
parentnode = parentnode != '' ? '?parent=' + parentnode : '';
}
constructor(private service: Service) { } }
@Injectable() export class DynamicDataSource {
dataChange: BehaviorSubject<DynamicFlatNode[]> = new BehaviorSubject<DynamicFlatNode[]>([]); get data(): DynamicFlatNode[] { return this.dataChange.value; } set data(value: DynamicFlatNode[]) { this.treeControl.dataNodes = value; this.dataChange.next(value); } constructor(private treeControl: FlatTreeControl,
private database: DynamicDatabase) { }
connect(collectionViewer: CollectionViewer): Observable<DynamicFlatNode[]> {
this.treeControl.expansionModel.onChange!.subscribe(change => {
if ((change as SelectionChange).added ||
(change as SelectionChange).removed) {
this.handleTreeControl(change as SelectionChange);
}
});
}
handleTreeControl(change: SelectionChange) {
if (change.added) {
}
toggleNode(node: DynamicFlatNode, expand: boolean) { const index = this.data.indexOf(node); if (expand) { if (node.level == 3) return; node.isLoading = true; if (node.children.length == 0) { const children = this.database.getData('Subject/scripts/Subjectw.ashx?parent=' + node.id, '', "").then( (response: any) => { const nodes = response.map( ContentNode => new DynamicFlatNode( ContentNode.Title, ContentNode.id, ContentNode.PID, ContentNode.Type, ContentNode.s, ContentNode.children, node.level + 1, ContentNode.children)) if (!children || index < 0) { // If no children, or cannot find the node, no op return; }
} }
@Component({ selector: 'Contenttree', templateUrl: './contenttree.component.html', styleUrls: ['./contenttree.component.css'], providers: [DynamicDatabase] }) export class ContenttreeComponent {
RootContents: DynamicFlatNode[] = []; constructor(database: DynamicDatabase, private service: Service) { this.treeControl = new FlatTreeControl(this.getLevel, this.isExpandable);
this.dataSource = new DynamicDataSource(this.treeControl, database);
}
dataSource: DynamicDataSource; treeControl: FlatTreeControl;
getLevel = (node: DynamicFlatNode) => { return node.level; };
isExpandable = (node: DynamicFlatNode) => { return node.expandable; };
hasChild = (_: number, _nodeData: DynamicFlatNode) => { return nodeData.expandable; };
hasNoContent = (: number, _nodeData: DynamicFlatNode) => { return _nodeData.Title === ''; };
checklistSelection = new SelectionModel(true / multiple /);
/* Whether all the descendants of the node are selected. / descendantsAllSelected(node: DynamicFlatNode): boolean { const descendants = this.treeControl.getDescendants(node); const descAllSelected = descendants.every(child => this.checklistSelection.isSelected(child) ); return descAllSelected; }
/* Whether part of the descendants are selected / descendantsPartiallySelected(node: DynamicFlatNode): boolean { const descendants = this.treeControl.getDescendants(node); const result = descendants.some(child => this.checklistSelection.isSelected(child)); return result && !this.descendantsAllSelected(node); }
/* Toggle the to-do item selection. Select/deselect all the descendants node / todoItemSelectionToggle(node: DynamicFlatNode): void { this.checklistSelection.toggle(node); const descendants = this.treeControl.getDescendants(node); this.checklistSelection.isSelected(node) ? this.checklistSelection.select(...descendants) : this.checklistSelection.deselect(...descendants);
}
/* Toggle a leaf to-do item selection. Check all the parents to see if they changed / todoLeafItemSelectionToggle(node: DynamicFlatNode): void { this.checklistSelection.toggle(node); this.checkAllParentsSelection(node); }
/ Checks all the parents when a leaf node is selected/unselected / checkAllParentsSelection(node: DynamicFlatNode): void { let parent: DynamicFlatNode | null = this.getParentNode(node); while (parent) { this.checkRootNodeSelection(parent); parent = this.getParentNode(parent); } }
/* Check root node checked state and change it accordingly / checkRootNodeSelection(node: DynamicFlatNode): void { const nodeSelected = this.checklistSelection.isSelected(node); const descendants = this.treeControl.getDescendants(node); const descAllSelected = descendants.every(child => this.checklistSelection.isSelected(child) ); if (nodeSelected && !descAllSelected) { this.checklistSelection.deselect(node); } else if (!nodeSelected && descAllSelected) { this.checklistSelection.select(node); } }
/ Get the parent node of a node / getParentNode(node: DynamicFlatNode): DynamicFlatNode | null { const currentLevel = this.getLevel(node);
} } `
thanks alot