angular timer directive not working with ionic framework

我们两清 提交于 2019-12-01 15:36:20

try looking at this code sample here: http://siddii.github.io/angular-timer/examples.html#/angularjs-single-timer

starting the timer in angular is done via

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

not

element.start();

BTW, your ng-app should be in the html/body tag, not in the timer tag.

here's angular way: http://plnkr.co/edit/ug4VqTkkFWlsYLy7uq4O

also use $broadcast events for control this directive

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

as per the discussion in comments, I am sharing the implementation of basic directive that I am using. This is not as generic as angular-timer, so you might need to tweak the little to suit your need.

first part : factory to hold the timer, start/stop, etc etc

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
    };
});

second part : the directive, which supports 2 operations

  1. boolean pause variable with 2 way binding

  2. on-timeout function : which will be called on timeout

  3. interval : in seconds, after which the on-timeout function would be called

    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,
     };
    }]);
    

I decided to not user the angular-timer directive as I was having issues with it reseting when ever I would change tabs as you can see from this example here.

Instead I based my timer of this fiddle.

You can see my final result in this pen. Which loads a timer in ionic, and maintains counting even whilst changing tabs. Going forward, would probably want to add some more changes to it such as can only click stop when the timer has started etc.

        <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>

as per your comments, I am providing another answer... the stopwatch factory, that I am using in my project. as per your requirement you can use service like below :

checkout the PLUNKER to have a practical example.

  1. Initially you see instruction page, where timer is initialized to 2 hours.

  2. Then move to questions 1, where timer starts

  3. from question 1 you can go to help page, where the timer pauses

  4. then you move back to question 2, where timer resumes...

on how to use :

  1. start init it on first page

    app.controller('view1Ctrl', function($scope, $csCountdown){
      $csCountdown.init(2 * 3600); // 2 hours
      $scope.countdown = $csCountdown.data;
    })
    
  2. start the counter on second page

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

you can display the value on any page using countdown.stringValue

<h1>Time : {{countdown.stringValue}}</h1>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!