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

AngularJS表格行独立倒计时与闪烁功能故障排查

解决AngularJS表格行独立倒计时问题

这是个典型的作用域污染问题——你把所有计时器的状态都存在了全局的$scope上,所以每一行调用timeInitializer时都会覆盖这些值,导致所有行共享同一个倒计时状态。咱们来把每个行的计时器状态独立绑定到对应的tckt对象上,让每行拥有自己的倒计时:

第一步:修改控制器中的timeInitializer函数

把原来存在$scope上的hrs、mins、secs、blinkAlarmOn和计时器实例都移到传入的tckt对象里,这样每个行的数据对象会维护自己的倒计时状态:

$scope.timeInitializer = function (tckt) {
    // 初始化当前行的状态,避免污染全局$scope
    tckt.blinkAlarmOn = false;
    const currentTimeUTCMiliSec = new Date(new Date().toUTCString()).getTime();
    const targetDeployDate = tckt.deploymentDatetime.split('.')[0] + "Z";
    const deployTimeUTCMiliSec = new Date(new Date(Date.parse(targetDeployDate)).toUTCString()).getTime();
    
    // 计算初始剩余时间,处理已过期情况
    let totalSecondLeft = Math.floor((deployTimeUTCMiliSec - currentTimeUTCMiliSec) / 1000);
    if (totalSecondLeft < 0) {
        tckt.hrs = 0;
        tckt.mins = 0;
        tckt.secs = 0;
        tckt.blinkAlarmOn = true;
        return;
    }
    
    // 转换为时分秒格式
    tckt.hrs = Math.floor(totalSecondLeft / 3600);
    totalSecondLeft %= 3600;
    tckt.mins = Math.floor(totalSecondLeft / 60);
    tckt.secs = totalSecondLeft % 60;
    
    // 保存计时器实例到tckt,方便后续清理
    tckt.countdownInterval = $interval(function () {
        if (tckt.secs > 0) {
            tckt.secs--;
        } else if (tckt.mins > 0) {
            tckt.mins--;
            tckt.secs = 59;
        } else if (tckt.hrs > 0) {
            tckt.hrs--;
            tckt.mins = 59;
            tckt.secs = 59;
        }
        
        // 倒计时结束逻辑
        if (tckt.hrs === 0 && tckt.mins === 0 && tckt.secs === 0) {
            $interval.cancel(tckt.countdownInterval);
            tckt.blinkAlarmOn = true;
        }
    }, 1000);
};

第二步:调整UI中的绑定和调用

现在UI需要绑定到tckt对象自身的属性,而不是全局$scope的属性,同时修改ng-init的传参:

<td>
    <div 
        ng-show="tckt.state=='DELAY_DEPLOYMENT'" 
        ng-init="timeInitializer(tckt)"
        ng-class="{ 'blink': tckt.blinkAlarmOn }"
    >
        {{ tckt.hrs.toString().padStart(2, '0') }}:{{ tckt.mins.toString().padStart(2, '0') }}:{{ tckt.secs.toString().padStart(2, '0') }}
    </div>
</td>

第三步:添加闪烁样式(可选)

确保你的CSS中有对应的闪烁样式:

.blink {
    animation: blink 1s infinite;
}

@keyframes blink {
    0% { opacity: 1; }
    50% { opacity: 0; }
    100% { opacity: 1; }
}

额外注意:内存泄漏防护

如果表格行可能被动态移除(比如分页、筛选),记得在移除行时取消对应的计时器,避免内存泄漏。比如在控制器中添加清理逻辑:

// 假设你有移除行的函数
$scope.removeTicket = function(tckt) {
    if (tckt.countdownInterval) {
        $interval.cancel(tckt.countdownInterval);
    }
    // 其他移除逻辑...
};

这样修改后,每一行的倒计时状态都会独立存储在对应的tckt对象中,不会互相干扰,倒计时结束后也只会让当前行闪烁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:30:48