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?

3
  • 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? Commented Feb 20, 2017 at 14:26
  • I want execute a method with all the elements in the list to use the lightslider plugin. sachinchoolur.github.io/lightslider/examples.html Commented Feb 20, 2017 at 14:32
  • Try this stackoverflow.com/a/30257914/1299394 Commented Feb 20, 2017 at 15:10

2 Answers 2

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');
})
Sign up to request clarification or add additional context in comments.

Comments

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();
        }
    }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.