0

I'm trying to use the jQuery scollsnap plugin in AngularJS, and have tried following the guide from this other post. However, it neither gives an error nor does it work.

This is what I had.

App.directive('scrollsnap', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            angular.element(element).scrollsnap({ snaps: 'section' });
        }
    };
}); 

And in my HTML:

<body scrollsnap class="... ... ...>
Community
  • 1
  • 1
mushroom
  • 1,909
  • 3
  • 16
  • 33

1 Answers1

1

Your jquery plugin may need to be initialized after the view has been rendered.

Try using $timeout:

App.directive('scrollsnap', function($timeout) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            $timeout(function() {
               angular.element(element).scrollsnap({ snaps: 'section' });
            });
        }
    };
}); 
Michael Kang
  • 52,003
  • 16
  • 103
  • 135
  • Hmm, is this the best-practice? Using timeouts to wait for the view to render? – mushroom Aug 04 '14 at 04:59
  • Yes.. if you're mixing jquery plugins with angular. There is no _after_ _render_ event in angular that you can hook into, but often times you need one when initializing jquery plugins. $timeout accomplishes this. The angular way might be to not use jquery plugins. – Michael Kang Aug 04 '14 at 05:11
  • Here is a feature request for the Angular team to introduce an _after_ _render_ event: https://github.com/angular/angular.js/issues/734. In the discussion, they suggest best practice is not use code (jquery plugins) that necessitates the need for an after render process. Compilation is a continuous process, so to discourage the (bad) practice of hooking in code that runs after the render event, they don't make it easy or intuitive. $timeout waits until after the render phase has finished before executing the code - not by design, its just how it works. – Michael Kang Aug 04 '14 at 05:21
  • Before reaching for your jquery toolbox, check if there is an angular way to do the same thing using directives. You might be able to do the same thing with a fraction of the code. If you still can't find a way, check with the community, maybe they have ideas. If you still can't find a way, ask google, or look through some Angular textbooks. Basically, only reach for your jquery toolbox as a last resort. And since it is a last resort, might as well use $timeout to initialize your plugin. – Michael Kang Aug 04 '14 at 05:37
  • Thanks, but unfortunately, I don't seem to find any plugins for AngularJS that snaps the scroll to elements. I'll probably have to go with this and will give it a try. – mushroom Aug 04 '14 at 06:39