2

Я пытаюсь создать свою собственную карусель изображений как директиву angularjs; Я хочу сохранить его как легкий и unopinionated, как possibile, так что я думал, что я просто создать <carousel></carousel> оболочку для набора <img> элементов, например, так:

<carousel> 
    <img ng-repeat="image in images" ng-src="{{image.src}}" alt=""/> 
</carousel> 

Что директива делает просто создать <div class="carousel"> элемент, в который преобразуются изображения. Теперь я все еще не закодировал ту часть, где изображения скользят или исчезают в/из-за того, что есть одна проблема, с которой я хотел бы сначала отказаться: я хочу назначить карусель и все изображения на той же высоте (вычисленные как высота кратчайшего изображения), чтобы избежать изменения высоты карусели при отображении более высокого изображения или не обрезать изображение, если карусель имеет фиксированную высоту.

Итак, я записал this JSFiddle, чтобы продемонстрировать, но пока лучшее, что я нашел для вычисления высот преобразованных изображений, зависит от двух вложенных $timeout s с задержкой в ​​100 мс. Мне кажется, что это скорее хак, чем что-либо.
Так что мне было интересно, есть ли «правильный» способ сделать это в angularjs. Приветствия.

P.S. На стороне примечания, я также не люблю получать корневой элемент шаблона директивы, <div class="carousel"> в моем случае, используя element.children() ... нет ли простого способа ссылаться на него в angularjs? Посмотрел вокруг, но не кубиками.

+0

, потому что без '$ timeout' ваша директива будет выполняться до' нг-repeat' завершает оказание 'img' теги –

+1

Отличный подход, престиж. :) –

+0

Да .. Я думал, что я реализовал это .. и он работает..Глад, чтобы помочь вам .. :) –

ответ

3

Вам нужно написать еще одну директивы, которая будет интимным угловой кодом, нг-повтор визуализации всех img тегов, то на что мы добавим событие слушателя, который будет задавать высоту и ширину этого элемента на load этим образом.

Директива

.directive("carousel", ["$timeout", function ($timeout) { 
    return { 
     restrict: "E", 
     transclude: true, 
     template: "<div class=\"carousel\" ng-transclude></div>", 
     link: function (scope, element, attrs) { 
      var div = element.children(); 
      scope.$on('ngRepeatDone', function() { 
       element.find('img').on('load', function() { 
        var images = div.children(); 
        var minHeight = Math.min.apply(null, _.pluck(images, "height")); 
        angular.forEach([div, images], function (e) { 
         e.css({ 
          height: minHeight + "px" 
         }); 
        }); 
        scope.$apply(); 
       }); 
      }); 
     } 
    } 
}]) 

NgRepeateDone

.directive('myPostRepeatDirective', function() { 
    return function (scope, element, attrs) { 
     if (scope.$last) { 
      scope.$emit('ngRepeatDone') 
     } 
    }; 
}); 

Demo JSFiddle

+1

'scope. $ Apply();' хороший здесь ..... ^^ – Jai

+0

@ Jai да .. там нам это нужно, потому что мы делаем манипуляции с областью на DOM-событии, как здесь, его '.on ('load')' –