如何使用Angular 5指令实现树形表格行的隐藏与显示
Hey there! Let's get that tree table expand/collapse functionality working, while keeping your existing row highlighting. Here's how to fix it step by step:
1. Fix Your Data Structure
First, your current demoData doesn't distinguish parent rows from child rows, and there's no way to track expansion state. Update it to include child items and an isExpanded flag for parent rows:
// Define a clear interface for your table items (optional but recommended) interface TableItem { one: string; two: string; three: string; children?: TableItem[]; isExpanded?: boolean; } // Example data with parent-child relationships demoData: TableItem[] = [ { one: 'Parent Row 1', two: 'Parent 1 - Col 2', three: 'Parent 1 - Col 3', isExpanded: false, children: [ { one: 'Child Row 1.1', two: 'Child 1.1 - Col 2', three: 'Child 1.1 - Col 3' }, { one: 'Child Row 1.2', two: 'Child 1.2 - Col 2', three: 'Child 1.2 - Col 3' } ] }, { one: 'Parent Row 2', two: 'Parent 2 - Col 2', three: 'Parent 2 - Col 3', isExpanded: false }, { one: 'Parent Row 3', two: 'Parent 3 - Col 2', three: 'Parent 3 - Col 3', isExpanded: false }, { one: 'Parent Row 4', two: 'Parent 4 - Col 2', three: 'Parent 4 - Col 3', isExpanded: false } ];
2. Add Expansion Toggle Logic to Your Component
Add a method to toggle the isExpanded state when a parent row is clicked:
// Inside your component class toggleExpand(item: TableItem): void { // Only toggle if the item has children if (item.children && item.children.length > 0) { item.isExpanded = !item.isExpanded; } }
3. Update the Table Template to Render Tree Structure
Modify your HTML to render parent rows, and conditionally show child rows based on the isExpanded state. We'll also keep your appBetterHighlight directive:
<div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>one</th> <th>two</th> <th>three</th> </tr> </thead> <tbody> <!-- Parent Rows --> <tr *ngFor="let item of demoData" appBetterHighlight (click)="toggleExpand(item)" style="cursor: pointer;" <!-- Visual cue that row is clickable --> > <td>{{item.one}}</td> <td>{{item.two}}</td> <td>{{item.three}}</td> </tr> <!-- Child Rows (Conditionally Visible) --> <ng-container *ngFor="let parent of demoData"> <tr *ngFor="let child of parent.children" *ngIf="parent.isExpanded && parent.children" appBetterHighlight style="padding-left: 2rem;" <!-- Indent child rows for tree structure --> > <td>{{child.one}}</td> <td>{{child.two}}</td> <td>{{child.three}}</td> </tr> </ng-container> </tbody> </table> </div>
4. Fix Your Highlight Directive
Your current directive keeps the row blue even after mouse leave. Let's fix that and add customizable colors:
import { Directive, Renderer2, OnInit, ElementRef, HostListener, HostBinding, Input } from '@angular/core'; @Directive({ selector: '[appBetterHighlight]' }) export class BetterHighlightDirective implements OnInit { @Input() defaultColor: string = 'transparent'; @Input() highlightColor: string = 'blue'; @HostBinding('style.backgroundColor') backgroundColor: string; constructor(private elRef: ElementRef, private renderer: Renderer2) { } ngOnInit() { this.backgroundColor = this.defaultColor; } @HostListener('mouseenter') mouseover(eventData: Event) { this.backgroundColor = this.highlightColor; } @HostListener('mouseleave') mouseleave(eventData: Event) { this.backgroundColor = this.defaultColor; // Revert to default on mouse leave } }
How It Works
- Expansion State: Each parent row has an
isExpandedflag that toggles when clicked - Child Rendering: Child rows only render if their parent's
isExpandedistrueand the parent has children - Highlighting: The directive now correctly reverts to the default background color when the mouse leaves the row, and supports custom colors via inputs
- Visual Cues: We added
cursor: pointerto parent rows and indentation to child rows to make the tree structure clear
内容的提问来源于stack exchange,提问作者user9795620

