Search code examples
angularjsonsen-ui

How to manage certain carousel in <ons-list>


I have almost the same question as in Onsen UI Carousel Swipe list item question. But I need to manage a certain carousel (ccall functions a la setActiveCarouselItemIndex()) in ons-list-item tapped on instead of removing list member. I wrote the code below:

 <ons-page ng-controller="TaskListCtrl">
  <ons-toolbar>
    <div class="center">Home</div>
  </ons-toolbar>

  <ons-list>
    <ons-list-item modifier="chevron" ng-controller="TaskItemCtrl" ng-repeat="task in tasks">
      <ons-row>
        <ons-col width="60px">
          {{ task.id }}
        </ons-col>
        <ons-col>
          <ons-carousel var="taskCarousel" auto-scroll style="width: 100%; height: 70px" ng-click="nextView()">
            <ons-carousel-item>
              View #1 {{ task.descr }}
            </ons-carousel-item>
            <ons-carousel-item>
              View #2 {{ task.details }}                  
            </ons-carousel-item>
          </ons-carousel>
        </ons-col>
      </ons-row>
    </ons-list-item>
  </ons-list>
</ons-page>

The code is:

var app = angular.module('app', ['onsen']);

app.controller('AppController', function($scope) {

});

app.controller('TaskListCtrl', function($scope) {
    $scope.tasks = [
            {
                id: "1",
                descr: "Task Description #1",
                details: "Details of Task #1"
            },
            {
                id: "2",
                descr: "Task Description #2",
                details: "Details of Task #1"
            },
            {
                id: "3",
                descr: "Task Description #3",
                details: "Details of Task #1"
            },
            {
                id: "4",
                descr: "Task Description #4",
                details: "Details of Task #1"
            }
        ];

    });

    app.controller('TaskItemCtrl', ['$scope', function($scope) {
        $scope.nextView = function() {
            var currentIndex = $scope.taskCarousel.getActiveCarouselItemIndex();
            $scope.taskCarousel.setActiveCarouselItemIndex((currentIndex + 1) % 2);            alert($scope.task.descr + "\n" + $scope.taskCarousel.toString());

        };
    }]);

A tapping any item in list manages only a carousel at the last ons-list-item.

Thank you in advance...


Solution

  • In your code you are naming every carousel item as var="taskCarousel". The problem is that every new carousel item with ng-repeat is "overwriting" the previous var="taskCarousel", so in the end it can only access to the last one. A possible solution would be to name your items dynamically with, for example, your tasks ids:

    <ons-carousel var="{{task.id}}" auto-scroll style="width: 100%; height: 70px" ng-click="nextView(task.id)">
       <ons-carousel-item>
          View #1 {{ task.descr }}
       </ons-carousel-item>
            <ons-carousel-item>
           View #2 {{ task.details }}                  
       </ons-carousel-item>
    </ons-carousel>
    

    Notice that now we also send this id when an item is clicked with ng-click="nextView(task.id)". Therefore, in the controller we will need to use bracket notation instead of dot notation to access the element since the parameter we are sending is just a string:

    app.controller('TaskItemCtrl', ['$scope', function($scope) {
       $scope.nextView = function(taskID) {
           var currentIndex = $scope[taskID].getActiveCarouselItemIndex();
           $scope[taskID].setActiveCarouselItemIndex((currentIndex + 1) % 2);
       };
    }]);
    

    You can try it in Codepen here. Hope it helps :)