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

如何在ASP.NET Core MVC表格行中显示基于数据库时间的独立倒计时器?

问题分析与解决方案

你的问题核心是全局变量覆盖导致所有倒计时共用同一个时间值,加上脚本逻辑没有为每个购物车独立初始化定时器。下面是具体的修复步骤:

1. 修正Razor视图中的倒计时元素

将原来动态生成类名的<p>标签,改为使用统一类名+data属性存储每个购物车的目标倒计时时间:

<table id="example" class="table table-striped dt-responsive nowrap" width="100%" cellspacing="0">
  <thead class="thead-light">
    <tr>
      <th>@Html.DisplayNameFor(model => model.CartNumber)</th>
      <th>@Html.DisplayNameFor(model => model.CartType)</th>
      <th>@Html.DisplayNameFor(model => model.Status)</th>              
      <th>@Html.DisplayNameFor(model => model.CustomerID)</th>
      <th>@Html.DisplayNameFor(model => model.Duration)</th>
      <th>Remaining Time</th>
      <th>@Html.DisplayNameFor(model => model.ImageContent)</th>
    </tr>
  </thead>
  <tbody>
    @foreach (var item in Model)
    { 
    <tr>
      <td>@Html.DisplayFor(modelItem => item.CartNumber)</td>
      <td>@Html.DisplayFor(modelItem => item.CartType)</td>
      <td>@Html.DisplayFor(modelItem => item.Status)</td>
      <td>@Html.DisplayFor(modelItem => item.CustomerID)</td>
      <td>@Html.DisplayFor(modelItem => item.Duration)</td>
      <!-- 统一类名 + data属性存储目标时间 -->
      <td><p class="countdown-timer" data-countdown="@item.DurationCountdown"></p></td>
      <td><img height="50" width="70" src='@Url.Action("BookedCarts", "File", new { id = item.ID })' /></td>
    </tr>
    }
  </tbody>
</table>

2. 编写通用的倒计时初始化脚本

移除原来循环内的重复脚本,改用一个全局脚本为每个购物车独立创建定时器,避免全局变量覆盖:

<script>
document.addEventListener('DOMContentLoaded', function() {
  // 批量获取所有倒计时元素
  const timerElements = document.querySelectorAll('.countdown-timer');

  timerElements.forEach(element => {
    // 从当前元素的data属性中读取专属目标时间
    const targetTime = new Date(element.dataset.countdown).getTime();

    // 为每个元素创建独立的定时器
    const intervalId = setInterval(() => {
      const now = new Date().getTime();
      const timeLeft = targetTime - now;

      // 计算剩余时分秒(因为预订时长1-6小时,无需计算天数)
      const hours = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60));
      const seconds = Math.floor((timeLeft % (1000 * 60)) / 1000);

      if (timeLeft > 0) {
        element.textContent = `${hours}h ${minutes}m ${seconds}s`;
      } else {
        // 倒计时结束,清除定时器并更新文本
        clearInterval(intervalId);
        element.textContent = "EXPIRED";
        // 可选:这里可以添加购物车过期后的业务逻辑,比如发送请求更新状态
      }
    }, 1000);
  });
});
</script>

原代码问题总结

  1. 全局变量覆盖:如果原脚本写在foreach循环内,每次循环都会生成全局的countDownDate和x变量,后续循环会覆盖前面的值,导致所有定时器共用最后一个购物车的时间。
  2. 元素选择逻辑错误:原代码中过期时只更新第一个.demo元素,无法正确处理所有购物车的过期状态。
  3. 冗余脚本:循环内生成多个重复脚本,既影响性能又容易引发变量冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:05:23