Recently diving into Angular, I'm working on a feature where users can toggle the visibility of a row of details by simply clicking on the item row. The scenario involves a table displaying log entries, each with a hidden row underneath containing specific information. Upon clicking a log entry row, the details row should appear or disappear.
Initially, I handled this within the event handler by manipulating the DOM to adjust the style of the details row. However, considering Angular's best practices, I found a more suitable solution after some exploration:
The key HTML snippet:
<tbody>
<ng-container *ngFor="let entry of log; let i=index">
<tr class="log-entry" (click)="displayRow[i] = !displayRow[i]">
<td class="datetime">{{entry.datetime}}</td>
<td class="actor">{{entry.actor}}</td>
<td class="summary">{{entry.summary}}</td>
</tr>
<tr class="details" [style.display]="displayRow[i] ? 'table-row' : ''">
<td colspan="3">
<pre>{{entry.details}}</pre>
</td>
</tr>
</ng-container>
</tbody>
And here's the respective code:
import { Component, OnInit } from '@angular/core';
import { LogEntry } from '../log';
import { LogService } from '../log.service';
@Component({
selector: 'app-log',
templateUrl: './log.component.html',
styleUrls: ['./log.component.styl']
})
export class LogComponent implements OnInit {
log: LogEntry[]
// An array of booleans used in the template to track toggled detail rows
displayRow: boolean[] = []
constructor(private logService: LogService) { }
ngOnInit() {
this.logService
.getLog()
.then(this.onLogUpdated)
.catch(this.onLogUpdateError)
}
// Event handlers
private onLogUpdated = (log: LogEntry[]) => {
console.debug("Redrawing log")
this.displayRow = log.map((x) => false)
this.log = log
console.log(this.displayRow)
console.log(this.log)
}
private onLogUpdateError = (error) => {
console.error("Error when trying to get log from log service")
console.error(error)
}
}
Although I'm effectively managing the state of the details row with an array of booleans, I wonder if there's a cleaner and more Angular-friendly way to achieve this behavior solely within the template. Any insights?