0

On my page I programmatically generate a food/drinks menus from a json file with Angular.js. The problem is with the "perfect-scrollbar" used for scrolling the angular-generated content, which appears to require a scroll-wheel event to initialise on these menus. This makes it impossible to scroll on devices without a scroll-wheel. Apart from the angular-generated content other pages initialize perfect-scrollbar properly. This gave me a clue that the problem might lie with the interaction between jQuery world (perfect-scrollbar is a jQuery plugin) and Angular world.
The site is themockingbird.co.uk - navigate to the "Food" and "Drinks" to see the problem in action - can't scroll the content (the perfect-scrollbar won't appear) unless with the mouse scroll-wheel.
I've written this little directive:

mainMenuApp.directive('scrollBar', function(){
    return {
        restrict: 'C',
        template: '<div ng-transclude></div>',
        transclude: true,
        scope: {},
        link: function(scope, element, attrs){
            $(element).perfectScrollbar();
            //element.perfectScrollbar(); - doesn't work
            //angular.element(element).perfectScrollbar(); - doesn't work
        }
    }
});

to facilitate the "perfect-scrollbar" via angular for the two menus, but this did not solve the problem.
How can I make the perfect-scrollbar work perfectly with angular (pun intended :)?
I appreciate your time.
cheers
Jared

EternalHour
  • 8,308
  • 6
  • 38
  • 57
Jared Tomaszewski
  • 793
  • 4
  • 17
  • 31
  • I can scroll in Chrome 34 on Mac OSX without a problem using the perfect scroll bar (the scrollbar with the orange arrows I guess). In which browser have you tried it? – Mandy Schoep Apr 24 '14 at 20:41
  • It works for me in Chrome & Firefox 28. Worked with both my laptop touchpad & mouse wheel. – EnigmaRM Apr 24 '14 at 20:51

3 Answers3

1

At the time your link function is executed, your menu-food.json and menu-drink.json are not arrived yet and perfectScrollbar needs an update at the time the data arrive, called with:

$(element).perfectScrollbar('update');

Since you have no architecture for handling the food and drinks lists as decoupled watchable values in a controller attached by your directive, you may simply broadcast an event from the root scope, listened by your directive link functions, thus updating the perfectScrollbar instance at the right moment.

atondelier
  • 2,424
  • 15
  • 11
  • Does the trick. Thought this would be an issue, and tried to use the 'update' before, but now I realize I was trying to do it synchronously, which of course didn't work. Thanks. – Jared Tomaszewski Apr 25 '14 at 08:11
  • One question: How do I make sure that the event is broadcasted AFTER all ng-repeats are done? – Jared Tomaszewski Apr 25 '14 at 12:44
  • Short way: have your event listener set a flag, and have your directive watch this flag. Longer but better way: implement controller communication via directives. – atondelier Apr 25 '14 at 12:49
1

I had the same problem when using https://github.com/itsdrewmiller/angular-perfect-scrollbar - the following "add-on directive", solved this problem:

.directive('psMouseOver', function () {    
    return {       
        link: function(scope, element) {
            element.bind("mouseover", function(e){
                e.stopPropagation();
                e.preventDefault();    
                element.perfectScrollbar('update');
            });   
        }
    }
});

In your case however, one would just add those lines and write your directive as:

mainMenuApp.directive('scrollBar', function(){
    return {
        restrict: 'A',
        template: '<div ng-transclude></div>',
        transclude: true,
        scope: {},
        link: function(scope, element, attrs){
            element.perfectScrollbar();
            element.bind("mouseover", function(e){
                e.stopPropagation();
                e.preventDefault();    
                element.perfectScrollbar('update');
            }); 
        }
    }
});
Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92
0

That happen in my case when Angular.js files loaded before JQuery and Perfect Scrollbar scripts files includes.

<script src="assets/libs/jquery.min.js"></script>
<script src="assets/libs/jquery.mousewheel.js"></script>
<script src="assets/libs/perfect-scrollbar.js"></script>

Try to load firstly JQuery, Perfect Scrollbar, and just after AngularJS.

CETb
  • 344
  • 1
  • 3
  • 11