Используя setInterval в angularjs factory
Я пытался использовать код, указанный в angularjs docs (здесь: http://jsfiddle.net/zGqB8/)
Он просто реализует время factory и использует $timeout для обновления объекта времени через каждую секунду.
angular.module('timeApp', [])
.factory('time', function($timeout) {
var time = {};
(function tick () {
time.now = new Date().toString();
$timeout(tick, 1000); // how to do it using setInterval() ?
})();
return time;
});
Как бы это сделать, используя функцию setInterval() вместо $timeout()?
Я знаю, что нужно использовать scope.$apply()
для входа в контекст выполнения angular, но как это работает в функции factory? Я имею в виду, что в контроллере у нас есть область видимости, но у нас нет возможности в функции factory?
Ответы
Ответ 1
Вы можете использовать $timeout
в качестве интервала.
var myIntervalFunction = function() {
cancelRefresh = $timeout(function myFunction() {
// do something
cancelRefresh = $timeout(myIntervalFunction, 60000);
},60000);
};
Если представление уничтожено, вы можете уничтожить его при прослушивании на $destroy
:
$scope.$on('$destroy', function(e) {
$timeout.cancel(cancelRefresh);
});
Ответ 2
Обновить
Angular реализовала функцию $interval в версии 1.2 - http://docs.angularjs.org/api/ng.$interval
Предыдущий пример ниже, игнорируйте, если вы не используете версию старше 1.2.
Реализация setInterval в Angular -
Я создал factory имя timeFunctions, которое предоставляет $setInterval и $clearInterval.
Обратите внимание, что в любое время, когда мне нужно было изменить область видимости в factory, я передал ее. Я не уверен, что это соответствует "Angular способу", но он работает хорошо.
app.factory('timeFunctions', [
"$timeout",
function timeFunctions($timeout) {
var _intervals = {}, _intervalUID = 1;
return {
$setInterval: function(operation, interval, $scope) {
var _internalId = _intervalUID++;
_intervals[ _internalId ] = $timeout(function intervalOperation(){
operation( $scope || undefined );
_intervals[ _internalId ] = $timeout(intervalOperation, interval);
}, interval);
return _internalId;
},
$clearInterval: function(id) {
return $timeout.cancel( _intervals[ id ] );
}
}
}
]);
Пример использования:
app.controller('myController', [
'$scope', 'timeFunctions',
function myController($scope, timeFunctions) {
$scope.startFeature = function() {
// scrollTimeout will store the unique ID for the $setInterval instance
return $scope.scrollTimeout = timeFunctions.$setInterval(scroll, 5000, $scope);
// Function called on interval with scope available
function scroll($scope) {
console.log('scroll', $scope);
$scope.currentPage++;
}
},
$scope.stopFeature = function() {
return timeFunctions.$clearInterval( $scope.scrollTimeout );
}
}
]);
Ответ 3
Не могли бы вы вызвать обычный метод JavaScript, а затем в этом методе оберните код Angular с помощью $apply?
Пример
timer = setInterval('Repeater()', 50);
var Repeater = function () {
// Get Angular scope from a known DOM element
var scope = angular.element(document.getElementById(elem)).scope();
scope.$apply(function () {
scope.SomeOtherFunction();
});
};
Ответ 4
Последний релиз-кандидат (1.2.0 rc3) поддерживает интервал. См. changelog