我有一个基本上只是倒数计时器的指令。用法非常简单,只要startFlag
为真,就开始倒计时,当它为假时停止计数,并在时间用完时调用超时函数:
app.directive('countdownTimer', [ '$interval',
function($interval) {
var directive = {
restrict: 'E',
templateUrl: 'app/common/countdownTimer.html',
scope: {
timeAllotted: '=',
startFlag: '=',
timeoutCallback: '='
},
link: link
};
return directive;
function link(scope, element, attrs) {
var timeLeft;
// Set watch on time allotted
scope.$watch('timeAllotted', function(newValue) {
timeLeft = newValue;
scope.minutes = getMinutes(timeLeft);
scope.seconds = getSeconds(timeLeft);
});
// Set watch on start flag
scope.$watch('startFlag', function(newValue) {
if(newValue) {
scope.timer = $interval(tickFunction, 1000);
} else {
$interval.cancel(scope.timer);
}
});
function getFormattedTimeValue(val) {
if(val < 10) {
val = '0' + val;
}
return val;
}
function getMinutes(secs) {
return getFormattedTimeValue(parseInt(secs / 60));
}
function getSeconds(secs) {
return getFormattedTimeValue(secs % 60);
}
function tickFunction(triggerTimeout) {
timeLeft = timeLeft - 1;
scope.minutes = getMinutes(timeLeft);
scope.seconds = getSeconds(timeLeft);
if(timeLeft <= 0) {
scope.timeoutCallback();
scope.startFlag = false;
}
}
}
}
]);
我的问题是上面的timeAllotted
上的手表有效,但只是第一次。它由从远程数据源加载的对象的属性设置:
<countdown-timer
data-time-allotted="vm.timeRemaining"
data-start-flag="vm.taskStarted"
data-timeout-callback="vm.taskTimeout">
</countdown-timer>
所有这一切都很有效。当来自timeLeft
的数据发生变化时(该变量初始化为0,然后在另一个对象变为可用时更新),该指令会正确更新其本地vm.timeRemaining
变量。
但是,我还希望在超时条件发生后提供延长时间的选项。但是当我在超时条件之后更新vm.timeRemaining
时,不会触发指令上的$watch
。
这是我目前尝试更新控制器的剩余时间:
function extendTime() {
// This should reset the clock back to it's starting time,
// but it doesn't change!
vm.timeRemaining = vm.task.time_limit;
vm.hasAccess = true;
dismissModal();
// Added timeout so I could try $scope.$apply().. didn't help
$timeout(function() {
$scope.$apply();
// This confirms that vm.timeRemaining is updating here, but the
// $watch on timeAllotted isn't firing in the directive
console.log('timeRemaining updated');
console.log(vm.timeRemaining);
startTask();
}, 50);
}
对于它的价值,任务超时并没有做太多有趣的事情:
function taskTimeout() {
// Cancels timer
pauseTask();
// Synchronizes data with API
syncTick();
// Opens a modal
vm.modalInstance = $modal.open({
templateUrl: 'app/common/timeoutModal.html',
scope: $scope
});
}
我的指令vm.timeRemaining
上的extendTime
绑定变量无法识别我的控制器$watch
函数中更新timeAllotted
的原因吗?
更新
下面是从我的datacontext中检索任务的函数(它基本上只是一个存储库的容器)。一旦承诺得到解决,vm.timeRemaining
就会更新,在这种情况下,指令正确$watch
:
function getTask() {
return datacontext.task.loadForLevel(level)
.then(function(results) {
vm.task = results[0];
vm.timeRemaining = vm.task.time_limit;
})
;
}