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>