Angular директива таймера, не работающая с ионным каркасом

У меня возникают проблемы с реализацией директивы таймера angular с ионной структурой. http://siddii.github.io/angular-timer/

Когда я реализую код с помощью bower или google cdn, у меня нет проблем.

    <!DOCTYPE html>
    <html>
    <head>
    <title>Plain Javascript Timer Example</title>
    <script src="../bower_components/angular/angular.min.js"></script>
    <script src="../app/js/timer.js"></script>
    <script>
    function startTimer() {
    document.getElementsByTagName('timer')[0].start();
    }
    function stopTimer() {
    document.getElementsByTagName('timer')[0].stop();
    }
    </script>
    </head>
    <body>
    <div>
    <h2>Plain JavaScript - Timer Example</h2>
    <h3><timer ng-app="timer"/></h3>
    <button onclick="startTimer()">Start Timer</button>
    <button onclick="stopTimer()">Stop Timer</button>
    </div>
    <br/>
    </body>
    </html>

Однако, когда я использую ионный пучок http://code.ionicframework.com/1.0.0-beta.13/js/ionic.bundle.js Я не могу заставить таймер работать. И, похоже, не возникают ошибки в консоли.

Это известная проблема?

Что может помешать работе?

Есть ли альтернативный таймер, который люди могут рекомендовать? Мне это показалось лучшим?

Ответ 1

попробуйте посмотреть здесь этот пример кода: http://siddii.github.io/angular-timer/examples.html#/angularjs-single-timer

запуск таймера в angular выполняется через

$scope.$broadcast('timer-stop');

не

element.start();

Кстати, ваше ng-приложение должно быть в теге html/body, а не в теге таймера.

Ответ 2

здесь angular способ: http://plnkr.co/edit/ug4VqTkkFWlsYLy7uq4O

также используют $broadcast events для управления этой директивой

$scope.start = function () {
  $scope.$broadcast('timer-start');
};

Ответ 3

в соответствии с обсуждением в комментариях, я разделяю реализацию базовой директивы, которую я использую. Это не такое общее, как angular -timer, поэтому вам может понадобиться настроить немного, чтобы удовлетворить ваши потребности.

первая часть: factory для хранения таймера, начала/остановки и т.д. и т.д.

csapp.factory("timerfactory", function () {
    var refresh = {
        suspend: false,
        pause: function () { refresh.suspend = true; },
        cont: function () { refresh.suspend = false; },
        toggle: function () { refresh.suspend = !refresh.suspend; },
        refreshText: function () { return refresh.suspend ? "Resume Refresh" : "Pause Refresh"; }
    };

    var timer = {
        timePending: 0,
        refreshInterval: 60,
        reset: function () { timer.timePending = timer.refreshInterval; },
        update: function () {
            if (timer.timePending < 0) timer.reset();
            timer.timePending--;
        },
        done: function () { return timer.timePending <= 0; },
        force: function () { timer.timePending = 0; }
    };

    return {
        refresh: refresh,
        timer: timer
    };
});

вторая часть: директива, которая поддерживает 2 операции

  • переменная boolean pause с привязкой по 2 способам

  • функция on-timeout: которая будет вызываться в тайм-ауте

  • интервал: в секундах, после которого функция on-timeout будет называться

    csapp.directive( "csAutoRefresh", [ "timerfactory", "Logger", "$ interval", function (factory, logManager, $interval) {

    var $log = logManager.getInstance('csAutoRefresh');
    
    var templateFn = function () {
        var template = '<div class="text-left alert alert-success nopadding"';
        template += 'style="margin-bottom: 0; margin-right: 0"> ';
        template += ' <button class="btn btn-link" data-ng-click="factory.refresh.toggle()">';
        template += '{{factory.refresh.refreshText()}}</button>';
        template += '<span>...Refreshing upload status in ';
        template += ' {{factory.timer.timePending}} seconds</span>';
        template += ' </div>';
        return template;
    };
    
    var linkFn = function (scope) {
        scope.pauseOn = false;
        scope.isprocessing = false;
        scope.factory = factory;
        if (angular.isDefined(scope.interval) && collosys.isNumber(parseInt(scope.interval)) && parseInt(scope.interval) > 0) {
            scope.factory.timer.refreshInterval = scope.interval;
        }
        factory.timer.reset();
    
        scope.$watch(function () {
            return factory.timer.timePending;
        }, function () {
            if (!factory.timer.done()) return;
            var result = scope.$eval(scope.onTimeout);
            if (angular.isObject(result) && angular.isFunction(result.then)) {
                scope.isprocessing = false;
                factory.timer.reset();
                result.finally(function () {
                    factory.timer.reset();
                });
            };
        });
    
        scope.$watch('pauseOn', function () {
            if (scope.pauseOn) {
                factory.refresh.pause();
            } else {
                factory.timer.reset();
                factory.refresh.cont();
            }
        });
    
        var updateTimer = function () {
            if (scope.isprocessing) return;
            if (factory.refresh.suspend) return;
            factory.timer.update();
        };
    
        var interval = $interval(updateTimer, 1000);
        scope.$on('$destroy', function () {
            $interval.cancel(interval);
        });
    };
    
    return {
        restrict: 'E',
        scope: { onTimeout: '&', pauseOn: '=', interval: '@' },
        template: templateFn,
        link: linkFn,
     };
    }]);
    

Ответ 4

Я решил не использовать директиву angular -timer, поскольку у меня возникали проблемы с ее реселлированием, когда я когда-либо менял вкладки, как вы можете видеть из этого пример здесь.

Вместо этого я основал свой таймер эту скрипту.

Вы можете увидеть мой окончательный результат в этой ручке. Которая загружает таймер в ионном режиме и поддерживает подсчет даже при изменении вкладок. Переход вперед, возможно, захочет добавить к нему еще несколько изменений, например, можно остановить только при запуске таймера и т.д.

        <script id="home.html" type="text/ng-template">
          <ion-view title="Home">
            <ion-content class="padding">
              <p>Home page</p>
                <h1>{{myStopwatch.data.hours | numberFixedLen:2}}:{{myStopwatch.data.minutes | numberFixedLen:2}}:{{myStopwatch.data.seconds | numberFixedLen:2}}</h1>
                <button ng-click='myStopwatch.start()'>Start</button>
                <button ng-click='myStopwatch.stop()'>Stop</button>
                <button ng-click='myStopwatch.reset()'>Reset</button>          
            </ion-content>
          </ion-view> 
        </script>

    <script>
    .filter('numberFixedLen', function () {
        return function (n, len) {
            var num = parseInt(n, 10);
            len = parseInt(len, 10);
            if (isNaN(num) || isNaN(len)) {
                return n;
            }
            num = ''+num;
            while (num.length < len) {
                num = '0'+num;
            }
            return num;
        };
    })
    .constant('SW_DELAY', 1000)
    .factory('stepwatch', function (SW_DELAY, $timeout) {
        var data = {
            seconds: 0,
            minutes: 0,
            hours: 0
        },
        stopwatch = null;

        var start = function () {
            stopwatch = $timeout(function () {
                data.seconds++;
                if (data.seconds >= 60) {
                    data.seconds = 00;
                    data.minutes++;
                    if (data.minutes >= 60) {
                        data.minutes = 0;
                        data.hours++;
                    }
                }
                start();
            }, SW_DELAY);
        };

        var stop = function () {
            $timeout.cancel(stopwatch);
            stopwatch = null;
        };

        var reset = function () {
            stop()
            data.seconds = 0;
        };
        return {
            data: data,
            start: start,
            stop: stop,
            reset: reset
        };
    })
    .controller('HomeTabCtrl', function($scope, $state, stepwatch) {
      $scope.myStopwatch = stepwatch;
    });
    </script>

Ответ 5

в соответствии с вашими комментариями, я предоставляю еще один ответ... секундомер factory, который я использую в своем проекте. согласно вашему требованию вы можете использовать сервис, как показано ниже:

ознакомьтесь с PLUNKER, чтобы получить практический пример.

  • Сначала вы видите страницу с инструкциями, где таймер инициализируется на 2 часа.

  • Затем перейдите к вопросам 1, где таймер запускается

  • из вопроса 1 вы можете перейти на страницу помощи, где таймер приостанавливает

  • то вы вернетесь к вопросу 2, где таймер возобновляется...

о том, как использовать:

  • запустить его на первой странице

    app.controller('view1Ctrl', function($scope, $csCountdown){
      $csCountdown.init(2 * 3600); // 2 hours
      $scope.countdown = $csCountdown.data;
    })
    
  • запустить счетчик на второй странице

    app.controller('view2Ctrl', function($scope, $csCountdown){
      $csCountdown.start();
      $scope.countdown = $csCountdown.data;
    })
    

вы можете отобразить значение на любой странице, используя countdown.stringValue

<h1>Time : {{countdown.stringValue}}</h1>