Статьи

Создание плагина для слайд-шоу с AngularJS

Прошли те времена, когда вы использовали для написания сотен строк jQuery для создания собственного слайдера изображений! Пришло время пойти Angular и достичь той же цели с меньшим, более простым кодом. Этот туториал покажет, как создать плагин для слайд-шоу с AngularJS. Мы будем использовать угловые директивы и анимацию для достижения этой цели. Если вы не знакомы с директивами, обязательно прочитайте мою серию директив AngularJS . Еще одна приятная особенность этого подхода заключается в том, что мы не собираемся писать ни одной строки jQuery! Как это круто? Итак, начнем.

Шаг 1: Создание директивы AngularJS

Когда дело доходит до AngularJS, сначала нужно разработать архитектуру приложения, а затем использовать соответствующую разметку / дизайн. Поскольку мы хотим, чтобы наш слайдер был автономным и легко подключался к существующему приложению AngularJS, создание директивы — правильный путь. Итак, начнем с пустой директивы с именем slider

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

sliderApp.directive('slider', function($timeout) {
  return {
    restrict: 'AE',
    replace: true,
    scope: {
      images: '='
    },
    link: function(scope, elem, attrs) {},
    templateUrl: 'templates/templateurl.html'
  };
});

Важно отметить, что мы выделили сферу действия нашей директивы. Поскольку нам потребуется несколько функций / свойств только для внутреннего использования, мы решили создать изолированную область вместо того, чтобы загрязнять родительскую область. Также мы должны иметь возможность принимать список изображений из родительской области для отображения. Вот почему мы используем = Наконец, шаблон для директивы находится внутри файла templateurl.html

Шаг 2: Настройте контроллер для предоставления изображений

Далее, давайте создадим контроллер, который создает массив из пяти объектов изображения в своей области видимости. Мы передадим эти изображения в директиву позже.

 sliderApp.controller('SliderController', function($scope) {
  $scope.images = [{
    src: 'img1.png',
    title: 'Pic 1'
  }, {
    src: 'img2.jpg',
    title: 'Pic 2'
  }, {
    src: 'img3.jpg',
    title: 'Pic 3'
  }, {
    src: 'img4.png',
    title: 'Pic 4'
  }, {
    src: 'img5.png',
    title: 'Pic 5'
  }];
});

Шаг 3: Напишите разметку директивы

Теперь вернемся к нашей директиве и создадим разметку. Поскольку директива должна отображать каждое изображение в массиве, мы будем использовать ng-repeat Также у нас будет две кнопки: prevnext Содержимое templates/templateurl.html

 <div class="slider">
  <div class="slide" ng-repeat="image in images" ng-show="image.visible">
    <img ng-src="img/{{image.src}}" />
  </div>
  <div class="arrows">
    <a href="#" ng-click="prev()">
      <img src="img/left-arrow.png" />
    </a>
    <a href="#" ng-click="next()">
      <img src="img/right-arrow.png" />
    </a>
  </div>
</div>

Разметка довольно проста. Свойство srcimage Свойство image.visible Когда мы перемещаемся вперед / назад к следующему изображению, нам нужно установить для свойства visibletrue Для остальных объектов imagefalse Мы также передали функции next()prev()ng-click Свойство image.title

Шаг 4: Обновите Директиву

Нам нужно отслеживать текущее видимое изображение. Для этого мы будем использовать свойство currentIndex У нас также есть функция next()currentIndexprev() Давайте обновим функцию link

 scope.currentIndex = 0; // Initially the index is at the first image

scope.next = function() {
  scope.currentIndex < scope.images.length - 1 ? scope.currentIndex++ : scope.currentIndex = 0;
};

scope.prev = function() {
  scope.currentIndex > 0 ? scope.currentIndex-- : scope.currentIndex = scope.images.length - 1;
};

Это просто увеличивает / уменьшает currentIndex Но нам нужно определить, когда происходит это изменение, и соответствующим образом сделать изображение в currentIndexvisibletrue Поскольку мы уже передали image.visibleng-show Мы также должны следить за областью действия директив для изменений в currentIndex Добавьте следующий код в конец предыдущего фрагмента кода:

 scope.$watch('currentIndex', function() {
  scope.images.forEach(function(image) {
    image.visible = false; // make every image invisible
  });

  scope.images[scope.currentIndex].visible = true; // make the current image visible
});

Шаг 5: анимируйте слайдер

В Angular 1.2 была представлена ​​новая анимационная структура, которую можно использовать для бесшовной связи CSS3-анимаций с различными событиями. Вам просто нужно указать анимацию, а Angular позаботится об остальном. Например, когда элемент скрыт, Angular автоматически добавит классы, такие как ng-hide-addng-hide-active Вы можете написать CSS для этих классов, чтобы выполнить желаемую анимацию. Угловая анимация выходит за рамки этого урока. Тем не менее, я советую вам пройти этот ресурс, чтобы узнать об анимации. Чтобы добавить анимацию, обновите модуль следующим образом:

 var sliderApp = angular.module('sliderApp', ['ngAnimate']);

И включите следующий скрипт в HTML после скрипта Angular:

 <script src="http://code.angularjs.org/1.2.9/angular-animate.min.js"></script>

Затем добавьте следующие правила CSS для описания переходов:

 .slide.ng-hide-add,
.slide.ng-hide-remove {
  -webkit-transition: all linear 0.5s;
  -moz-transition: all linear 0.5s;
  -o-transition: all linear 0.5s;
  transition: all linear 0.5s;
  display: block!important;
}
.slide.ng-hide-add.ng-hide-add-active,
.slide.ng-hide-remove {
  opacity: 0;
}
.slide.ng-hide-add,
.slide.ng-hide-remove.ng-hide-remove-active {
  opacity: 1;
}

Шаг 6: Используйте Директиву

Теперь пришло время использовать директиву в HTML. При использовании директивы мы также должны передать директиву массив images

 <body ng-controller="SliderController">
  <h1>Slider Using AngularJS</h1>
  <slider images="images" />
</body>

Это все! Наш новый угловой слайдер готов. В целях стилизации мы можем включить следующий CSS:

 * {
  font-family: 'Open Sans', sans-serif;
}
.center-grey {
  background: #f2f2f2;
}
.slider {
  position: relative;
  padding: 5px;
  width: 610px;
  margin: auto;
  margin-top: 40px;
}
.slide {
  position: absolute;
  top: 0;
  left: 0;
  box-shadow: 0px 0px 15px #999;
}
.arrows {
  position: absolute;
  top: 10px;
  right: 20px;
}
.arrows img {
  height: 32px;
}
h1 {
  text-align: center;
  padding: 10px;
  font-size: 40px;
  color: #222;
}

бонус

В дополнение к ответам на следующие / предыдущие клики мы также можем захотеть, чтобы наш слайдер автоматически переходил к следующему изображению через определенный интервал. Для этого мы можем использовать сервис Angular’s $timeout Измените директиву, как показано ниже, чтобы объявить зависимость от $timeout

 sliderApp.directive('slider', function($timeout) {
  ...
  // configuarations here
});

И добавьте следующий фрагмент к функции linknext()

 var timer;
var sliderFunc = function() {
  timer = $timeout(function() {
    scope.next();
    timer = $timeout(sliderFunc, 5000);
  }, 5000);
};

sliderFunc();

scope.$on('$destroy', function() {
  $timeout.cancel(timer); // when the scope is getting destroyed, cancel the timer
});

Вывод

Мы подошли к концу урока и узнали, как создать слайдер изображений AngularJS с помощью директивы (с небольшой анимацией). Мы достигли этого с минимальным количеством кода JavaScript и без манипуляций с JQuery DOM. В Angular может быть много способов добиться того же, и этот урок показал только один путь. Если вы можете придумать лучший способ или есть что добавить / спросить, не стесняйтесь комментировать.

Исходный код полного приложения доступен для скачивания на GitHub . Вы также можете проверить живую демонстрацию приложения.