1

I'm having an issue trying to make an Angular Directive in Typescript after a ng-repeat finish.

This is how I'm trying to make the directive work:

export interface ILightSliderInitDirectiveScope extends ng.IScope {
}
export class LightSliderInitDirective implements ng.IDirective {
    public static DirectiveName: string = "lightSliderInit";
    link = (scope: ILightSliderInitDirectiveScope, $element: any, attrs: ng.IAttributes) => {
        if (scope.$watch('$scope.$last'))
            scope.$emit('ngRepeatFinished');
    }
}

At the controller I have this method:

_self.$scope.$on('ngRepeatFinished', function() {...});

And at the HTML:

<li ng-repeat="it in items" light-slider-init>...</li>

The problem is that the directive works, but it go inside the if condition in every iteration of the ng-repeat.

How can I solve this?

Divins Mathew
  • 2,908
  • 4
  • 22
  • 34
Calde8
  • 35
  • 4
  • I'm not sure you should be concerned with any "iteration" that may happen with an ng-repeat. All elements of it should be rendered during a single digest cycle, so for any normal use you should consider it as a single atomic operation. Why do you want this event? What do you plan to use it for? – Eric Simonton Feb 20 '17 at 14:26
  • I want execute a method with all the elements in the list to use the lightslider plugin. http://sachinchoolur.github.io/lightslider/examples.html – Calde8 Feb 20 '17 at 14:32
  • Try this http://stackoverflow.com/a/30257914/1299394 – AJ Richardson Feb 20 '17 at 15:10

2 Answers2

0

scope.$watch returns a deregistration function for this listener, so scope.$watch('whatever') is always truthy. And you should not add $scope to the watched expression since it is evaluated regarding to the $scope object.
Here is what your code should looks like:

scope.$watch('$last', $last => {
  if ($last) scope.$emit('ngRepeatFinished');
})
Zen
  • 5,065
  • 8
  • 29
  • 49
0

I would not recommend firing and event to do this because it makes it very difficult if you ever need 2 or more light sliders on the page.

Because this is in an ng-repeat, your link function will actually run for every instance in the repeater. So rather than $watching the value of $last, you should just execute your code on the last item in the repeater.

Code based on https://stackoverflow.com/a/30257914/1299394:

export class LightSliderInitDirective implements ng.IDirective {
    restrict: 'A',
    link: function(scope: ILightSliderInitDirectiveScope, element: JQuery, attrs) {
        if (scope.$last) {
            // This is the last item in the repeater
            // Instead of firing an event, just initialize the light gallery right here.
            element.parent().lightGallery();
        }
    }
};
Community
  • 1
  • 1
AJ Richardson
  • 6,610
  • 1
  • 49
  • 59