可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am having issues with implementing the angular timer directive with the ionic framework.
http://siddii.github.io/angular-timer/
When I implement the code using bower or the google cdn I have no issues.
<!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>
However when I use the ionic bundle
http://code.ionicframework.com/1.0.0-beta.13/js/ionic.bundle.js
I can not get the timer to work.
And do not seem to get any errors in the console.
Is this a known issue?
What would be stopping it from working?
Is there an alternate timer that people can reccomend? This one seemed the best to me?
回答1:
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.
回答2:
here's angular way:
http://plnkr.co/edit/ug4VqTkkFWlsYLy7uq4O
also use $broadcast events for control this directive
$scope.start = function () {
$scope.$broadcast('timer-start');
};
回答3:
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
boolean pause variable with 2 way binding
on-timeout function : which will be called on timeout
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,
};
}]);
回答4:
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>
回答5:
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.
Initially you see instruction page, where timer is initialized to 2 hours.
Then move to questions 1, where timer starts
from question 1 you can go to help page, where the timer pauses
then you move back to question 2, where timer resumes...
on how to use :
start init it on first page
app.controller('view1Ctrl', function($scope, $csCountdown){
$csCountdown.init(2 * 3600); // 2 hours
$scope.countdown = $csCountdown.data;
})
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>