基于其他div的ngIf生成div及Angular表格表头与数据行实现问询
1. Generating a <div> Based on Another <div>'s *ngIf Condition
If you want one <div> to render only when another <div> is present (controlled by the same conditional logic), here are straightforward, maintainable approaches:
Shared Component Property: The simplest method is to use a single boolean property in your component to drive both
*ngIfdirectives. This keeps your logic centralized:// Component.ts showRelatedElements = true;<!-- Template.html --> <div *ngIf="showRelatedElements" class="primary-div">Primary Content</div> <div *ngIf="showRelatedElements" class="secondary-div">Secondary Content (only shows with primary)</div>Group with
<ng-container>: If you want to apply the condition to multiple elements without adding an extra DOM node, wrap them in<ng-container>(a lightweight container that doesn't render to the DOM):<ng-container *ngIf="showRelatedElements"> <div class="primary-div">Primary Content</div> <div class="secondary-div">Secondary Content</div> </ng-container>Avoid DOM-Driven Checks: While you technically can check if an element exists using template references and
ViewChild, this ties your logic to the DOM structure and is harder to maintain. Stick to component properties whenever possible.
2. Fixing Your Table Header & Data Row Implementation
Looking at your code snippet, the main issue is that the header is being rendered once per entry in the first key's TableMap (since isFirst is true for the outer loop, but you're nested inside the inner *ngFor over entries). This leads to duplicate headers. Here's how to fix it and create a clean, single-header table:
Step 1: Preprocess Valid Entries in Your Component
First, create a derived property to collect all entries that pass your checkIfThereIs validation. This simplifies your template logic:
// Component.ts get validTableEntries(): any[] { let validEntries: any[] = []; this.keys.forEach(key => { const mapEntries = this.TableMap[key.id] || []; validEntries.push(...mapEntries.filter(entry => this.checkIfThereIs(entry))); }); return validEntries; }
Step 2: Revised Template Code
Now, render the header only once if there are valid entries, followed by all data rows:
<!-- Template.html --> <div *ngIf="validTableEntries.length > 0" class="table-container"> <!-- Single Header Row --> <div class="display-flex table-header"> <div>Name</div> <div>Date</div> <div>Place</div> <div>Weight</div> <div>Height</div> </div> <!-- Data Rows --> <div *ngFor="let entry of validTableEntries" class="display-flex colorblue data-row"> <div class="border-r">{{ entry.name }}</div> <div class="border-r">{{ entry.date }}</div> <div class="border-r">{{ entry.place }}</div> <div class="border-r">{{ entry.weight }}</div> <div>{{ entry.height }}</div> </div> </div>
Key Improvements:
- Single Header: The header renders once, only when there are valid entries to display.
- Simplified Loops: We loop through pre-filtered entries instead of nested loops, making the template easier to read and debug.
- Logical Grouping: The wrapping
table-containerdiv ensures header and rows are visually and structurally linked.
Optional: Use Native <table> Elements
For better accessibility and semantic HTML, consider switching to native table elements. Here's a quick adaptation:
<table *ngIf="validTableEntries.length > 0" class="styled-table"> <thead> <tr> <th>Name</th> <th>Date</th> <th>Place</th> <th>Weight</th> <th>Height</th> </tr> </thead> <tbody> <tr *ngFor="let entry of validTableEntries" class="colorblue"> <td>{{ entry.name }}</td> <td>{{ entry.date }}</td> <td>{{ entry.place }}</td> <td>{{ entry.weight }}</td> <td>{{ entry.height }}</td> </tr> </tbody> </table>
内容的提问来源于stack exchange,提问作者John Theoden

