如何让一个元素的点击切换Angular 4中另一个元素的可见性?

问题描述:

我是Angular的新手,我试图让用户通过单击项目行来显示/隐藏一行细节。我有一个日志条目表。对于每个日志条目行,其下方都有一个隐藏行,其中包含详细信息。当单击日志条目行时,应切换详细信息行的可见性。如何让一个元素的点击切换Angular 4中另一个元素的可见性?

我最初在事件处理程序中通过爬行DOM和修改细节行的样式完全解决了这个问题。这并没有觉得很习惯到角,所以一些挖后,我现在有这样的解决方案:

相关的HTML:

<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> 

,代码:

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[] 

    // Used by the template to keep track of which rows have details toggled 
    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) 
    } 
} 

正如你看到的我必须维护一组布尔值来跟踪细节行的状态。我觉得应该有可能(和惯用)在模板中完成这一点,我只是不知道该怎么做。可能吗?

在通过Angular 4指南进一步阅读后,我发现了一种看起来更好的方法。它涉及到使用template reference variable标记的细节行,然后调用一个函数使用该变量隐藏的行:

<ng-container *ngFor="let entry of logToday; let i=index"> 
<tr class="log-entry" (click)="toggleRow(details)"> 
    <td class="datetime">{{entry.datetime}}</td> 
    <td class="actor">{{entry.actor}}</td> 
    <td class="summary">{{entry.summary}}</td> 
</tr> 
<tr #details class="details"> 
    <td colspan="3"> 
     <pre>{{entry.details}}</pre> 
    </td> 
</tr> 
</ng-container> 

它仍然需要一个功能组件代码中定义:

// Toggles the visibility of a table row 
toggleRow(row) { 
    if (row.style.display == '') { 
    row.style.display = 'table-row' 
    } 
    else { 
    row.style.display = '' 
    } 
} 

但至少比我以前的方法要干净得多。

注:我的切换功能是这样写的,因为详细信息行默认是隐藏的。