使用Angular UI Carousel进行`跟踪$ index'的问题

时间:2017-07-31 08:43:12

标签: angularjs angularjs-ng-repeat angular-ui-bootstrap

使用分页时,索引跟踪的$ index不会从零开始

我用角度ui bootsrap创建了一个旋转木马。 由于我加载了这么多图像(超过1,000张),我使用过滤器在分页中显示500张图片。

.filter('pages', function () {
    return function (input, currentPage, pageSize) {
        if (angular.isArray(input)) {
            var start = (currentPage - 1) * pageSize;
            var end = currentPage * pageSize;
            return input.slice(start, end);
        }
    };
})

控制器:

self.currentPage = 1;
self.itemsPerPage = 500;
self.maxSize = 10;

//imagesUrls is response.data from http call
angular.forEach(imagesUrls, function (parent) {
    var date = uibDateParser.parse(parent.fileCreationTime, 'M/d/yyyy 
                     hh:mm:ss a');
    // fill our slide arrays with urls
    // model update here
    self.slides.push({
        image: parent.fileName,
        time: date,
        id: parent.id
    });      
});
self.totalItems = self.slides.length;

我这样使用它:

<div uib-carousel 
     active="$ctrl.active"
     interval="$ctrl.myInterval"
     no-wrap="$ctrl.noWrapSlides"
     no-pause="true">
     <div uib-slide ng-repeat="slide in $ctrl.slides | pages: 
              $ctrl.currentPage : $ctrl.itemsPerPage track by $index" 
          index="$index">
         <img id="carousel-img" ng-src="{{slide.image}}">
         <div class="carousel-caption">
             <p>Index {{$index}}</p>
         </div>
     </div>
 </div>

<div class="row">
    <ul uib-pagination
        total-items="$ctrl.totalItems"
        items-per-page="$ctrl.itemsPerPage"
        ng-model="$ctrl.currentPage"
        max-size="$ctrl.maxSize"
        boundary-link-numbers="true"
        force-ellipses="true"
        class="pagination-sm">
    </ul>
 </div>

这可以按预期工作。

首次加载轮播时,索引为0.当它移动到下一张幻灯片时,索引为1,当您移动到下一张幻灯片时,索引为2。 当您显示当前图像的slide.id时,它也是2。

问题:

但是,当您单击第二个分页链接时,索引不会返回到零,它从幻灯片位于轮播中的最后一个索引处开始。

所以现在索引是2,当前图像的幻灯片ID是502。

如果滑动到索引20,然后单击分页链接,则索引仍为20.当您显示当前图像的幻灯片ID时,它将变为520。

有没有办法让索引再次从0开始,所以slide.id是500而不是502或520?

我希望我的问题很明确。

1 个答案:

答案 0 :(得分:2)

当有唯一的属性标识符可用时,请避免使用track by $index。处理所有唯一的对象时(如本例所示),最好让ng-repeat使用自己的跟踪而不是覆盖track by $index

 <div uib-slide ng-repeat="slide in $ctrl.slides | pages: 
          $ctrl.currentPage : $ctrl.itemsPerPage track by  ̶$̶i̶n̶d̶e̶x̶ slide.id" 
      index="$index">
     <img id="{{slide.id}}" ng-src="{{slide.image}}">
     <div class="carousel-caption">
         <p>Index {{ ̶$̶i̶n̶d̶e̶x̶ slide.id}}</p>
     </div>
 </div>

来自文档:

  
    

如果您正在处理具有唯一标识符属性的对象,则应使用此标识符而不是对象实例进行跟踪。如果您稍后重新加载数据,ngRepeat将不必为已呈现的项重建DOM元素,即使集合中的JavaScript对象已替换为新对象。对于大型集合,这可以显着提高渲染性能。

  
     

— AngularJS ng-repeat Directive API Reference - Tracking

The DEMO

&#13;
&#13;
angular.module("app",['ngAnimate', 'ngSanitize', 'ui.bootstrap'])
.controller("ctrl", function(uibDateParser) {
  var self = this;
self.currentPage = 1;
self.itemsPerPage = 10;
self.maxSize = 10;

var url = '//unsplash.it/200/100';
var imagesUrls = [];
for (let i=0; i<40; i++) {
  var slide = {
    fileName: url+"?image="+(1000+i),
    id: 'id'+(0+i+100),
    fileCreationTime: new Date()
  }
  imagesUrls.push(slide); 
}
self.slides = [];

//imagesUrls is response.data from http call
angular.forEach(imagesUrls, function (parent) {
    var date = uibDateParser.parse(parent.fileCreationTime,
        'M/d/yyyy hh:mm:ss a');
    // fill our slide arrays with urls
    // model update here
    self.slides.push({
        image: parent.fileName,
        time: date,
        id: parent.id
    });      
});
//console.log(self.slides);
self.totalItems = self.slides.length;
})
.filter('pages', function () {
    return function (input, currentPage, pageSize) {
        if (angular.isArray(input)) {
            var start = (currentPage - 1) * pageSize;
            var end = currentPage * pageSize;
            return input.slice(start, end);
        }
    };
})
&#13;
    <script src="//unpkg.com/angular/angular.js"></script>
    <script src="//unpkg.com/angular-animate/angular-animate.js"></script>
    <script src="//unpkg.com/angular-sanitize/angular-sanitize.js"></script>
    <script src="//unpkg.com/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>    
    <link href="//unpkg.com/bootstrap/dist/css/bootstrap.css" rel="stylesheet">

  <body ng-app="app" ng-controller="ctrl as $ctrl">
    <div class="container" uib-carousel 
     active="$ctrl.active"
     interval="$ctrl.myInterval"
     no-wrap="$ctrl.noWrapSlides"
     no-pause="true">
     <div uib-slide ng-repeat="slide in $ctrl.slides | pages: 
              $ctrl.currentPage : $ctrl.itemsPerPage track by slide.id" 
          index="$index">
         <img id="{{slide.id}}" ng-src="{{slide.image}}">
         <div class="carousel-caption">
             <p>Index {{slide.id}}</p>
         </div>
     </div>
 </div>

<div class="row container">
    <ul uib-pagination
        total-items="$ctrl.totalItems"
        items-per-page="$ctrl.itemsPerPage"
        ng-model="$ctrl.currentPage"
        max-size="$ctrl.maxSize"
        boundary-link-numbers="true"
        force-ellipses="true"
        class="pagination-sm">
    </ul>
 </div>
  </body>
&#13;
&#13;
&#13;