Angular Material Tree:如何仅为二级节点设置自定义图标
Got it, let's fix this up for you! The key here is to check each node's depth so we can render the arrow icon for first-level nodes and your custom icon for all nodes from the second level down. Here's a step-by-step implementation:
1. Make sure you can access the node's level
First, confirm your tree control can return the depth of each node. If you're using Angular Material's NestedTreeControl, it already has a built-in getLevel() method. For example, if your tree control is set up like this:
treeControl = new NestedTreeControl<YourNodeType>(node => node.children);
You're good to go—treeControl.getLevel(node) will give you the depth of any node (starting at 0 for top-level nodes).
If you're using a custom node structure without a built-in level method, you can add a level property to your node data when building the tree, or write a helper function to calculate it.
2. Update your mat-tree template to use conditional icons
Modify your template to swap icons based on the node's level. We'll use Angular's *ngIf and <ng-template> to handle the two cases:
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl"> <!-- Template for leaf nodes --> <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding> <!-- Show empty space to align with expandable top-level nodes, custom icon for others --> <ng-container *ngIf="treeControl.getLevel(node) === 0; else customLeafIcon"> <span style="width: 40px; display: inline-block;"></span> </ng-container> <ng-template #customLeafIcon> <div class="div-tree-close"></div> </ng-template> {{node.name}} </mat-tree-node> <!-- Template for expandable nodes --> <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding> <!-- Arrow toggle for top-level nodes, custom icon + toggle for children --> <ng-container *ngIf="treeControl.getLevel(node) === 0; else customExpandIcon"> <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> </ng-container> <ng-template #customExpandIcon> <!-- Custom icon with toggle functionality --> <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name"> <div class="div-tree-close"></div> <!-- Optional small arrow to show expand/collapse state --> <mat-icon class="tiny-toggle-icon"> {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}} </mat-icon> </button> </ng-template> {{node.name}} </mat-tree-node> <style> .div-tree-close { margin-right: 8px; height: 12px; width: 12px; background-color: #003d99; display: inline-block; vertical-align: middle; } .tiny-toggle-icon { font-size: 14px; vertical-align: middle; } </style> </mat-tree>
3. Tweak based on your needs
- If your top-level nodes start at level 1 instead of 0, just change the condition to
treeControl.getLevel(node) === 1. - If you don't want a toggle arrow next to the custom icon for child nodes, remove the
<mat-icon>element inside thecustomExpandIcontemplate. - Adjust the
.div-tree-closestyles (size, margin, color) to match your desired custom icon.
4. Double-check your hasChild function
Make sure your hasChild helper correctly identifies expandable nodes:
hasChild = (_: number, node: YourNodeType) => !!node.children && node.children.length > 0;
This setup will keep the default arrow toggles for all first-level nodes, and show your custom blue square icon for every node from the second level down—exactly what you're looking for!
内容的提问来源于stack exchange,提问作者FX_Sektor

