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

时间:2017-04-04 02:57:15

标签: typescript angular4

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

我最初通过抓取DOM并修改详细信息行的样式在事件处理程序中完全解决了这个问题。这对Angular来说并不是非常惯用,所以在经过一番挖掘后我现在有了这个解决方案:

相关的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)
  }
}

如您所见,我必须维护一组布尔值以跟踪详细信息行的状态。我觉得应该可以(和惯用)在模板中完成这个,我只是不知道该怎么做。有可能吗?

1 个答案:

答案 0 :(得分:0)

通过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 = ''
  }
}

但至少它比我之前的方法更清洁。

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