You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular ngFor循环内多ngIf切换异常:点击设置计时器按钮输入框不显示

解决Angular ngFor内计时器交互的显示问题

咱先把问题根源揪出来:你点击「设置计时器」按钮后按钮消失,但输入框没显示,核心是状态变量的逻辑没对应上——你用toggleTimerInput存的是布尔值,但模板里判断的是toggleTimerInput === i(索引值),这肯定匹配不上啊!而且ngFor循环里每个项得有独立状态,所以变量应该存当前激活的索引,不是布尔值。

第一步:修正组件内的状态变量

先把组件里的三个状态变量改成存储索引(或null表示无激活项),这样每个列表项的状态能独立控制:

// 组件.ts文件里的变量定义
toggleTimerInput: number | null = null; // 存当前显示输入框的项索引
toggleTimerActive: number | null = null; // 存当前运行计时器的项索引
remaining: number = 0;
settime: number = 0;
times: any[] = []; // 你的列车数据数组

第二步:修正模板里的交互逻辑

接下来简化模板里的判断条件和点击事件,别用复杂的三元表达式绕晕自己:

<div *ngFor="let time of times; let i = index" attr.data="{{time.Direction}}">
  <div class="card">
    <div class="card-body" style="text-align: left;">
      <!-- 列车信息部分保留不变 -->
      <div class="row">
        <strong><span class="col-sm">Due in: {{time.Duein}} mins</span></strong>
        <span class="col-sm">Direction {{time.Direction}}</span>
        <span class="col-sm">Destination: {{time.Destination}}</span>
      </div>
      <div class="row">
        <span class="col-sm">Expected Arrival {{time.Exparrival}}</span>
        <span class="col-sm">Train type {{time.Traintype}}</span>
      </div>
      <div class="row">
        <span class="col-sm">Last Location: {{time.Lastlocation}}</span>
      </div>
      <hr />

      <!-- 「设置计时器」按钮:无输入框、无运行计时器时才显示 -->
      <i 
        *ngIf="toggleTimerInput !== i && toggleTimerActive !== i"
        (click)="toggleTimerInput = i"
        class="far fa-clock"
      > Set timer</i>

      <!-- 计时器输入框:当前索引匹配toggleTimerInput时显示 -->
      <div class="md-form" *ngIf="toggleTimerInput === i">
        <input 
          mdbInput 
          type="tel" 
          [(ngModel)]="settime" 
          (keydown.enter)="startTimer(i); toggleTimerInput = null; toggleTimerActive = i"
          class="form-control" 
          placeholder="Set timer (In minutes)" 
        />
      </div>

      <!-- 运行中的计时器:当前索引匹配toggleTimerActive时显示 -->
      <div class="timer" *ngIf="toggleTimerActive === i">
        <i class="far fa-clock" (click)="endTimer(i)"> Stop Timer</i>
        {{remaining | time}}
      </div>
    </div>
  </div>
</div>

第三步:完善计时器的方法逻辑

最后调整startTimer和endTimer方法,确保计时器结束后自动重置状态:

startTimer(index: number) {
  // 把输入的分钟转换成秒,初始化剩余时间
  this.remaining = this.settime * 60;
  const timerInterval = setInterval(() => {
    this.remaining--;
    if (this.remaining <= 0) {
      clearInterval(timerInterval);
      this.endTimer(index); // 计时器结束后自动重置状态
    }
  }, 1000);
}

endTimer(index: number) {
  this.toggleTimerActive = null; // 重置运行状态,回到显示设置按钮的状态
  // 这里可以加计时器结束后的提示逻辑,比如弹出通知
}

逻辑说明

  • 每个列表项的状态通过索引匹配控制,多个计时器不会互相干扰
  • 「设置计时器」按钮仅在无输入框、无运行计时器时显示
  • 点击设置按钮后,toggleTimerInput设为当前索引,触发输入框显示
  • 按下回车键后,启动计时器,设置toggleTimerActive为当前索引,同时关闭输入框
  • 点击停止或计时器结束后,重置toggleTimerActive,回到初始状态

内容的提问来源于stack exchange,提问作者Conor Donohoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:21:37