可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have this working implementation af a angularJS app which fetches some links from an URL and paint them. However the links on the URL are being updated constantly, I would like to update periodcially this $scope.listlinks, let say every 10 seconds.
I tried playing with setInterval with no luck.
Javascript
var App = angular.module('App', []); App.controller('ListLinksCtrl', function get($scope, $http ) { $http.get('http://example_url.com/my_changing_links_json').then( function(res){$scope.listlinks = res.data;}); } );
HTML
回答1:
While jvandemo's answer will work, I think it can be improved slightly. By using setInterval
, it breaks the dependency injection convention that Angular follows and makes unit testing of the controller difficult.
Angular doesn't currently support setInterval
through its built-in services, but you can use the $timeout
service to produce the same functionality. I'd change the controller to this:
app.controller('MainCtrl', function($scope, $http, $timeout) { // Function to get the data $scope.getData = function(){ $http.get('style.css') .success(function(data, status, headers, config) { // Your code here console.log('Fetched data!'); }); }; // Function to replicate setInterval using $timeout service. $scope.intervalFunction = function(){ $timeout(function() { $scope.getData(); $scope.intervalFunction(); }, 1000) }; // Kick off the interval $scope.intervalFunction(); });
回答2:
2016
$interval is made for this:
$interval(function() { // your stuff }, 1000);
Don't forget to inject $interval
in your controller
app.controller('ExampleController', ['$scope', '$interval',function($scope, $interval) { $interval(function() { // your stuff , 1000); }]);
https://docs.angularjs.org/api/ng/service/$interval
回答3:
You can use the setInterval function but you need to encapsulate your logic in a function like this:
app.controller('MainCtrl', function($scope, $http) { // Function to get the data $scope.getData = function(){ $http.get('style.css') .success(function(data, status, headers, config) { // Your code here console.log('Fetched data!'); }); }; // Run function every second setInterval($scope.getData, 1000); });
I've created a working plnkr for your at: http://plnkr.co/edit/vNCbBm45VYGzEQ7cIxjZ?p=preview
Hope that helps!
回答4:
This answer builds off of drew.walker's answer, but makes it so that changing controllers will not spawn multiple endlessly running refreshes. It also runs getData
immediately, instead of delaying it 1 second.
It depends on you using Angular routes and setting Ctrls in them. If you don't, you'll need another way to determine if this controller is in scope.
app.controller('MainCtrl', function($scope, $rootScope, $route, $timeout) { // Function to get the data $scope.getData = function() { ... }; // Get the data immediately, interval function will run 1 second later $scope.getData(); // Function to replicate setInterval using $timeout service. $scope.intervalFunction = function() { var currentCtrl = $route.current.$$route.controller; var currentlyRunning = $rootScope.myAppMainCtrlRefreshRunning; //do not run if the MainCtrl is not in scope //do not run if we've already got another timeout underway (in case someone jumps back and forth between //controllers without waiting 1 second between) if (currentCtrl === "MainCtrl" && !currentlyRunning) { $timeout(function() { $rootScope.myAppMainCtrlRefreshRunning = true; $scope.getData(); $scope.intervalFunction(); $rootScope.myAppMainCtrlRefreshRunning = false; }, 1000); }; }; // Kick off the interval $scope.intervalFunction(); });
回答5:
I had to change to order to make it work:
From
$scope.intervalFunction(); $rootScope.myAppMainCtrlRefreshRunning = false;
to
$rootScope.myAppMainCtrlRefreshRunning = false; $scope.intervalFunction();
Otherwise the loop only executes once
回答6:
You can try the implementation of promises/deferred using $q provider.
https://docs.angularjs.org/api/ng/service/$q
回答7:
Try this it worked fine for me. $scope.intervalFunction = function(){ if ($location.$$absUrl === "current url") { $timeout(function() { $scope.showAllEmployeeTracking(); $scope.intervalFunction(); console.log("loading Interval") }, 10000) } }; // Kick off the interval $scope.intervalFunction();
回答8:
A better solution is to use Angular $interval and $destroy providers Example:
var stop=$interval(function () { function_call(); }, 12000) $scope.stopInterval = function () { if (angular.isDefined(stop)) { $interval.cancel(stop); stop = undefined; } }; $scope.$on('$destroy', function () { // Make sure that the interval is destroyed too $scope.stopInterval(); });