lightGallery (плагин jQuery) в AngularJS

Я пытаюсь заставить плагин lightGallery jQuery ( http://sachinchoolur.github.io/lightGallery/index.html) работать с AngularJS.

Я нашел несколько ответов, в которых говорилось, что мне нужна директива, поэтому я создал следующее:

.directive('lightGallery', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            jQuery(element).lightGallery();
        }
    };
})

Тогда, на мой взгляд, я делаю это:

<ul lightGallery>
    <li ng-repeat="photo in album.photos" data-src="{{photo.fullres}}">
        <img ng-src="{{photo.thumbnail}}" />
    </li>
</ul>

(Я тоже пробовал с <ul light-gallery>) Когда я запускаю страницу, ничего не происходит, когда я нажимаю на любую из миниатюр. Я могу положить alert() в функции ссылки, хотя, и это отображается.

Как я могу заставить AngularJS играть вместе с jQuery и этим плагином?

ОБНОВИТЬ:

После некоторой отладки кажется, что jQuery(element).lightGallery() выполняется до привязки модели к представлению. Поэтому вопрос в том, как я могу получить директиву для вызова, когда все связано, а не раньше.

3 ответа

Решение

Вызовите lightGallery после завершения рендеринга ng-repeat.
Вы можете просто изменить директиву, как это

.directive('lightgallery', function() {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      if (scope.$last) {

        // ng-repeat is completed
        element.parent().lightGallery();
      }
    }
  };
});

HTML

<ul>
  <li lightgallery ng-repeat="photo in photos" data-src="{{photo.fullres}}">
    <img ng-src="{{photo.thumbnail}}" />
  </li>
</ul>

Вот демо плнкр

Использование комбинации из 2 директив позволяет вам указывать родителя через директиву, а также передавать опции в переменную области действия, что дает возможность для дополнительной настройки Light Gallery. Вторичная директива инициирует связывание родителя (используя ту же идею, что и в решении @Clr)

Эта директива предназначена для родительского элемента, и вы можете передать переменную области galleryOptions, которая просто передается при связывании Light Gallery:

.directive('lightGallery', function() {
    return {
        restrict: 'A',
        scope: {
            galleryOptions: '='
        },
        controller: function($scope) {

            this.initGallery = function() {
                $scope.elem.lightGallery($scope.galleryOptions);
            };

        },
        link: function(scope, element, attr) {
            scope.elem = element;
        }
    }
})

Эта директива для каждого "элемента" в Light Gallery:

.directive('lightGalleryItem', function() {
    return {
        restrict: 'A',
        require: '^lightGallery',
        link: function (scope, element, attrs, ctrl) {

            if (scope.$last) {
                ctrl.initGallery();
            }

        }
    }
})

Результирующая разметка (которая действительно может быть чем угодно, указав selector опция при инициализации Light Gallery):

<ul light-gallery gallery-options="galleryOptions">
    <li ng-repeat="photo in album.photos" data-src="{{photo.fullres}}" light-gallery-item>
        <img ng-src="{{photo.thumbnail}}" />
    </li>
</ul>

Принимая во внимание, что параметры могут быть любыми допустимыми вариантами Light Gallery, такими как:

$scope.galleryOptions = {
    selector: '.file-trigger',
    ...
};

Без директивы..

HTML

<ul id="lightgallery">
  <li ng-repeat="image in album.images" data-src="{{imagem.fullres}}">
    <img ng-src="{{image.thumbnail}}" />
  </li>
</ul>

JavaScript

// $http, Restangular whatever to return data in album.images

// unbind before..
jQuery('#lightgallery').unbind().removeData();

// $timeout after
$timeout(function () {
  jQuery('#lightgallery').lightGallery();
}, 100);

Работает для меня..

Другие вопросы по тегам