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);
Работает для меня..