Запуск директивы после NG-Repeat
Итак, я ищу, чтобы поместить мою библиотеку плагинов в Angular везде, где только возможно, чтобы все было согласовано. Проблема, с которой я сталкиваюсь, заключается в получении директив для запуска после того, как все директивы его дочерних элементов запущены.
Чтобы дать немного ясности, целью здесь является упрощение для наших интеграторов (только для членов команды CSS/HTML) добавления динамических функциональных возможностей к элементам, просто пометив его функцией. В настоящее время они делают это с помощью атрибута data-features
. Например, для слайдера изображения они могут пометить UL атрибутом data-features="imageSlider"
, чтобы сделать этот UL слайдером.
В этих строках я работаю над перемещением этого слайдера изображения на angular. Я хочу, чтобы мои интеграторы могли написать что-то вроде:
<ul image-slider>
<li slide>
My Slide 1
</li>
<li slide>
My Slide 2
</li>
<li slide>
My Slide 3
</li>
</ul>
И я могу превратить это в слайдер изображения динамически. Вышеприведенное работает отлично, однако, если разметка выглядит следующим образом:
<ul image-slider>
<li slide ng-repeat="slide in data.slider.slides">
My Slide {{$index}}
</li>
</ul>
Затем ng-repeat
не заканчивается до запуска директивы image-slider
, что означает, что у меня нет доступа ко всем слайдам для работы с моей магией.
Есть ли способ, которым я могу сказать директиве image-slider
ждать, пока какие-либо директивы внутри нее закончатся до запуска?
Я уже прочитал следующие вопросы:
Ни у кого из них, похоже, нет ответа на эту проблему, поэтому я решил, что я собрал бы гораздо более сжатый вопрос в надежде найти ответ.
Ответы
Ответ 1
Таким образом, самый простой способ сделать это - использовать директиву директиву связи между дирекцией слайдов и директиву слайдера изображения. Вот что вы делаете:
app.directive("imageSlider", [ '$log', function($log) {
return {
scope: {
},
controller: function($scope) {
$scope.slides = [];
// this is a normal controller method that is NOT exposed to other directives
$scope.startGallery = function() {
};
// this method will be exposed to directives that require imageSlider
this.addSlide = function(slide) {
$scope.slides.push( slide );
}
}
};
} ]);
app.directive('slide', [ '$log', function($log) {
return {
require: "^imageSlider",
link: function($scope, elem, attribs, ctrls ) {
ctrls.addSlide( $scope );
}
};
} ] );
Таким образом, imageSlider может предоставить слайду интерфейс для взаимодействия. Обратите внимание на разницу в this.functionName vs $scope.functionName. Первое из них - способ разоблачения методов другими директивами.
Ответ 2
Я предлагаю гораздо более простой подход. Используйте функцию $timeout
. Если вы установите $timeout
на ноль, он будет работать точно после того, как все запустится:
app.directive("imageSlider", [ '$timeout', function($timeout) {
return function(scope, element, attrs)
{
// your data is defined in scope.data.slider.slides
$timeout(function()
{
// This code will run whenever the page has finished processing
// So it will run after ng-repeat has finished
}, 0);
}
}]);