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
相关产品推荐
相关产品推荐

