$watch не срабатывает в директиве после изменения в контроллере

У меня есть директива, которая в основном просто таймер обратного отсчета. Использование довольно просто, начните отсчет всякий раз, когда startFlag Значение true, остановите подсчет, когда оно ложно, и вызовите функцию тайм-аута, когда время истечет:

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 Переменная правильно, когда данные из vm.timeRemaining изменения (он инициализируется в 0 и затем обновляется, когда другой объект становится доступным).

Тем не менее, я хотел бы также предложить возможность продления времени, когда наступит условие тайм-аута. Но когда я обновляю 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 связанная переменная?

Обновить

Ниже приведена функция, которая извлекает задачу из моего текста данных (в основном это просто контейнер репозиториев). Как только обещание будет выполнено, vm.timeRemaining обновляется и, в этой ситуации, правильно $watchпод редакцией директивы:

function getTask() {
    return datacontext.task.loadForLevel(level)
        .then(function(results) {
            vm.task = results[0];
            vm.timeRemaining = vm.task.time_limit;
        })
    ;
}

0 ответов

Другие вопросы по тегам