【问题标题】:Never ending loop through array in AngularJS + setTimeout after each iteration每次迭代后,AngularJS + setTimeout 中的数组永不结束循环
【发布时间】:2018-03-07 16:33:01
【问题描述】:

如何在 AngularJS 中实现永无止境的循环?

我的尝试:

item_list = [{'id':1, 'photo':'path/src'}, {'id':2, 'photo':'path/src'}, {'id':3, 'photo':'path/src'}];

item_list.map(function(item) {
    setTimeout( function () {
         setCoverImage(item.photo);
    }, 5000);
)

我将使用来自item_list 的数据每 5 秒使用 setCoverImage() 更改封面图片。

【问题讨论】:

标签: angularjs settimeout infinite-loop


【解决方案1】:

首先你应该使用 AngularJS 的$interval。然后简单地增加一个计数器并使用它来访问控制器中当前元素的 photo 属性,并使用 ng-src 在你的 img 标记中反映该 URL。

<img ng-src="{{myCtrl.item_list[myCtrl.currentIndex].photo}}">

请注意,切勿为计数器分配与数组中的元素不对应的值。

if ((that.currentIndex + 1) >= that.item_list.length)

查看下面的完整示例

angular.module('appModule', []).controller('MyController', ['$scope', '$interval', function($scope, $interval) {
  this.item_list = [{
    'id': 1,
    'photo': 'https://i.pinimg.com/736x/32/76/a2/3276a2111c65b2131ef834736f47162b--birthday-kitten-birthday-hats.jpg'
  }, {
    'id': 2,
    'photo': 'http://img.playbuzz.com/image/upload/f_auto,fl_lossy,q_auto/cdn/154cb38e-55e3-4294-bffe-6906b6a41a6b/c33bcc8b-40be-49c9-bad1-ee85f8275189.jpg'
  }, {
    'id': 3,
    'photo': 'http://4.bp.blogspot.com/-J4ioK5aRks8/Tx8d9D5K54I/AAAAAAAAABM/iTL4sbsNYmc/w1200-h630-p-k-no-nu/Surprised+and+serious+kitten.jpg'
  }];
  var that = this;
  this.currentIndex = 0;
  $interval(function() {
    if ((that.currentIndex + 1) >= that.item_list.length) {
      that.currentIndex = 0;
    } else {
      that.currentIndex++;
    }
  }, 5000);
}])

angular.bootstrap(window.document, ['appModule'], {
  strictDi: true
});
<div ng-controller="MyController as myCtrl">
  <img ng-src="{{myCtrl.item_list[myCtrl.currentIndex].photo}}">
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>

【讨论】:

    【解决方案2】:

    像这样使用AngularJS的$interval服务:

    $interval( function () {
         setCoverImage(item.photo);
    }, 5000);
    

    【讨论】:

      【解决方案3】:

      在您的控制器/服务中注入$interval 服务(无论如何),然后您就可以使用这样的东西:

       let currentPhotoIdx = 0;
       const maxAvailablePhotoIdx = item_list.length - 1;
       $interval(() => {
          setCoverImage(item.photo[currentPhotoIdx]);
          currentPhotoIdx === maxAvailablePhotoIdx ? currentPhotoIdx = 0 : currentPhotoIdx++;
       }, 5000);
      

      【讨论】:

        【解决方案4】:

        $interval 的替代解决方案是$timeout:

        function setCoverImageLoop(photo) {
            $timeout(function () {
                setCoverImage(photo);
                setCoverImageLoop(photo);
            }, 5000);
        }
        
        item_list = [{'id':1, 'photo':'path/src'}, {'id':2, 'photo':'path/src'}, {'id':3, 'photo':'path/src'}];
        
        item_list.map(function(item) {
             setCoverImageLoop(item.photo);
        });
        

        这可能有点老派,主要针对喜欢来自setTimeout的人。

        【讨论】:

        • $timeout 不会无限循环。另一方面,递归调用很有效,很难得到冗长且“将来难以维护”的代码。记住这一点,这是一个有效的解决方案
        • 确实如此。它主要来自setTimeout 用于测量具有图形输出的帧之间的时间,但鉴于$interval 返回一个承诺,无论如何都会在每次迭代时得到通知,我怀疑我的解决方案完全是多余的。
        猜你喜欢
        • 1970-01-01
        • 2013-04-23
        • 1970-01-01
        • 2016-11-05
        • 2020-01-05
        • 1970-01-01
        • 2015-03-19
        • 1970-01-01
        • 2017-04-28
        相关资源
        最近更新 更多