<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
  <script data-require="angular.js@1.3.0" data-semver="1.3.0" src="https://code.angularjs.org/1.8.0/angular.js"></script>
  <script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
  <script data-require="bootstrap@3.1.1" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
  <script src="https://rawgit.com/michaelbromley/angularUtils-pagination/master/dirPagination.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.0/angular-touch.js"></script>
</head>

<body>
  <div class="carousel" ng-controller="carouselCtrl">
  <div class="carousel-inner">
    <div class="item" ng-class="{active: $index === currentIndex}" ng-repeat="slide in slides">
      <img ng-src="{{slide.image}}" alt="{{slide.title}}">
      <div class="carousel-caption">
        <h3>{{slide.title}}</h3>
        <p>{{slide.caption}}</p>
      </div>
    </div>
  </div>
  <a class="left carousel-control" ng-click="prevSlide()">
    <span class="glyphicon glyphicon-chevron-left"></span>
  </a>
  <a class="right carousel-control" ng-click="nextSlide()">
    <span class="glyphicon glyphicon-chevron-right"></span>
  </a>
</div>

</body>

</html>
var app = angular.module('myApp', ['ngTouch']);
// app.controller('carouselCtrl', function($scope,$interval) {
//   $scope.currentIndex = 0;
//   $scope.slides = [
//     {image: 'https://www.w3schools.com/howto/img_mountains_wide.jpg', title: 'Slide 1', caption: 'This is the caption for slide 1.'},
//     {image: 'https://www.w3schools.com/howto/img_fjords_wide.jpg', title: 'Slide 2', caption: 'This is the caption for slide 2.'},
//     {image: 'https://www.w3schools.com/howto/img_lights_wide.jpg', title: 'Slide 3', caption: 'This is the caption for slide 3.'},
//     {image: 'https://www.w3schools.com/howto/img_lights_wide.jpg', title: 'Slide 4', caption: 'This is the caption for slide 4.'},
//   ];
//   $scope.nextSlide = function() {
//     $scope.currentIndex = ($scope.currentIndex < $scope.slides.length - 1) ? ++$scope.currentIndex : 0;
//   };
//   $scope.prevSlide = function() {
//     $scope.currentIndex = ($scope.currentIndex > 0) ? --$scope.currentIndex : $scope.slides.length - 1;
//   };// Hàm tự động chuyển đổi slide
//   var interval = $interval(function() {
//     $scope.nextSlide();
//   }, 5000);
// });
app.controller('carouselCtrl', function($scope, $interval, $swipe) {
  // Giá trị mặc định
  $scope.currentIndex = 0;
  $scope.slides = [
    {image: 'https://www.w3schools.com/howto/img_mountains_wide.jpg', title: 'Slide 1', caption: 'This is the caption for slide 1.'},
    {image: 'https://www.w3schools.com/howto/img_fjords_wide.jpg', title: 'Slide 2', caption: 'This is the caption for slide 2.'},
    {image: 'https://www.w3schools.com/howto/img_lights_wide.jpg', title: 'Slide 3', caption: 'This is the caption for slide 3.'},
    {image: 'https://www.w3schools.com/howto/img_lights_wide.jpg', title: 'Slide 4', caption: 'This is the caption for slide 4.'},
  ];
  // Thời gian giữa các slide (miliseconds)
  var intervalTime = 5000;
  // Hàm chuyển đổi slide
  $scope.nextSlide = function() {
    $scope.currentIndex = ($scope.currentIndex < $scope.slides.length - 1) ? ++$scope.currentIndex : 0;
  };
  // Hàm chuyển đổi slide ngược lại
  $scope.prevSlide = function() {
    $scope.currentIndex = ($scope.currentIndex > 0) ? --$scope.currentIndex : $scope.slides.length - 1;
  };
  // Hàm tự động chuyển đổi slide
  var interval = $interval(function() {
    $scope.nextSlide();
  }, intervalTime);
  // Hủy bỏ interval khi người dùng tương tác với carousel
  $scope.$on('$destroy', function() {
    $interval.cancel(interval);
  });
  // Bắt đầu xử lý swipe
  $swipe.bind(angular.element(document.querySelector('.carousel-inner')), {
    start: function(coords) {
      $scope.startCoords = coords;
    },
    end: function(coords) {
      $scope.endCoords = coords;
      var xDiff = $scope.startCoords.x - $scope.endCoords.x;
      if (xDiff > 0 && xDiff > 50) {
        $scope.$apply(function() {
          $scope.nextSlide();
        });
      } else if (xDiff < 0 && Math.abs(xDiff) > 50) {
        $scope.$apply(function() {
          $scope.prevSlide();
        });
      }
    }
  });
});
.carousel-container {
  position: relative;
  width: 100%;
  height: 400px;
  overflow: hidden;
}
.carousel-slide {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 1s ease-in-out;
}
.carousel-slide.active {
  opacity: 1;
}
.carousel-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.carousel-caption {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  padding: 10px;
  color: #fff;
}
.carousel-caption h3 {
  margin: 0;
  font-size: 24px;}
.carousel-caption p {
margin: 5px 0 0;
font-size: 18px;
}
.carousel-prev, .carousel-next {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 50px;
font-weight: bold;
color: #fff;
cursor: pointer;
}
.carousel-prev {
left: 0;
}
.carousel-next {
right: 0;
}
# Pagination Directive

Yes, there are quite a few pagination solutions for Angular out there already, but what I wanted to do was make
something that would be truly plug-n-play - no need to do any set-up or logic in your controller. Just add
an attribute, drop in your navigation wherever you like, and boom - instant, full-featured pagination.

Code: https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination

More info: http://www.michaelbromley.co.uk/blog/108/paginate-almost-anything-in-angularjs