【问题标题】:AngularJS ngcontroller to be reloading data periodicallyAngularJS ngcontroller 定期重新加载数据
【发布时间】:2017-11-06 19:05:03
【问题描述】:

我有一个 angularJS 应用程序的工作实现,它从 URL 获取一些链接并绘制它们。 但是 URL 上的链接会不断更新,我想定期更新这个 $scope.listlinks,假设每 10 秒更新一次。

我尝试玩 setInterval 没有运气。

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

<div id="cnt1" ng-controller="ListLinksCtrl">
   <div ng-repeat="singlelink in listlinks">
        <a href="{{ singlelink.url }}"> 
           {{ singlelink.destination }} 
        </a>
   </div>
</div>

【问题讨论】:

  • setInterval 有什么问题?

标签: javascript angularjs


【解决方案1】:

虽然 jvandemo 的回答会起作用,但我认为它可以稍微改进。通过使用setInterval,它打破了 Angular 遵循的依赖注入约定,并使控制器的单元测试变得困难。

Angular 目前不通过其内置服务支持setInterval,但您可以使用$timeout 服务来产生相同的功能。我会将控制器更改为:

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

});

【讨论】:

  • 当代码写在控制器范围内时,这对我不起作用。该函数已触发,但页面上的模型未更新。
  • 这对我有用,但即使你离开控制器它也会继续运行,更糟糕的是,每次你导航回控制器时它都会产生另一个间隔!
  • 尾递归在 javascript 中是否正常工作(即是否没有像 intervalFunction 似乎自称那样慢慢填满堆栈的风险?)
  • 所以使用服务而不是控制器,这样只会发生一次。
  • Angular 现在有一个 $interval 服务可供您使用,您可以使用 $destroy 取消它,因此当您离开视图时它会停止:docs.angularjs.org/api/ng/service/$interval
【解决方案2】:

2016


$interval 就是为此而生的:

    $interval(function() {
        // your stuff          
    }, 1000);

别忘了在你的控制器中注入$interval

app.controller('ExampleController', ['$scope', '$interval',function($scope, $interval) {
      $interval(function() {
            // your stuff          
      , 1000); 
}]);

https://docs.angularjs.org/api/ng/service/$interval

【讨论】:

    【解决方案3】:

    您可以使用 setInterval 函数,但您需要将逻辑封装在这样的函数中:

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

    我已经为您创建了一个有效的 plnkr:http://plnkr.co/edit/vNCbBm45VYGzEQ7cIxjZ?p=preview

    希望有帮助!

    【讨论】:

    • 我认为这需要一个 $apply 因为 getData 函数是在角度框架之外调用的,因此 $scope 不会被更新。或者使用 Angular 的 $interval 或 $timeout
    【解决方案4】:

    这个答案建立在 draw.walker 的答案之上,但它使得更改控制器不会产生多个无休止的运行刷新。它还会立即运行getData,而不是延迟 1 秒。

    这取决于您使用 Angular 路由并在其中设置 Ctrl。如果不这样做,则需要另一种方法来确定此控制器是否在范围内。

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

    【讨论】:

    • $$ 据我所知表示 Angular 内部的内容 - 如有更改,恕不另行通知。
    【解决方案5】:

    我必须更改订单才能使其正常工作:

    来自

    $scope.intervalFunction();
    $rootScope.myAppMainCtrlRefreshRunning = false;
    

    $rootScope.myAppMainCtrlRefreshRunning = false;
    $scope.intervalFunction();
    

    否则循环只执行一次

    【讨论】:

      【解决方案6】:

      你可以尝试使用 $q 提供者来实现 promises/deferred。

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

          更好的解决方案是使用 Angular $interval$destroy 提供程序 示例:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-05-26
            • 2014-09-05
            • 1970-01-01
            • 1970-01-01
            • 2017-05-28
            • 1970-01-01
            • 2016-07-22
            • 1970-01-01
            相关资源
            最近更新 更多