Search code examples
angularjscontrollerfactoryangular-servicesng-class

AngularJS factory inside ng-class on body tag not working


Was told to create service/factory and use it on global controller. It's my first time hearing global controller. Anyways, I created a factory called Scroll and injected it on our main.controller.js. The function in the factory is isScrollingEnabled which returns true or false. The other function is setScrolling which will set the variable to true or false. The default value is set to true.

Inside the main controller, I have this code

$scope.scrollEnabled = Scroll.isScrollingEnabled();
console.log('value of $scope.scrollEnabled', $scope.scrollEnabled);

That code spits out true in the console which is good.

on my template, I'm using it this way. I have button that sets scrolling to false. The value in the console spits out false which is good.

<body ng-class="{ 'scrolling' : scrollEnabled }">

However, it's not working. If I change it to the code written below, it works

<body ng-class="{ 'scrolling' : false }">

So I guess, it's not in scope especially ui-view is in index.html and main.controller.js and main.html will be loaded in the ui-view. The < body > is before this which tells me, any scope inside main.controller.js will not work outside of ui-view.

So what's the solution for this?

Sorry for not posting the factory. Here it is

  .factory('Scroll', function() {

    var scrollEnabled = true; // i then changed it to false hoping it will work, it didn't

    var ScrollEvent = {
      isScrollingEnabled: function () {
        return scrollEnabled;
      },
      disablePageScrolling: function() {
        scrollEnabled = false;
      }
    };

    return ScrollEvent;
});

Solution

  • The $scope of the controller you're attaching the value to doesn't extend to the <body> element. Instead, you can whip together a directive:

    .directive('shouldScroll', function (Scroll) {
      return {
        restrict: 'A',
        link: function ($scope, elem) {
          $scope.$watch(Scroll.isScrollingEnabled, function (n) {
            if (n) {
              elem.addClass('scrolling');
            } else if (n === false) {
              elem.removeClass('scrolling');
            }
          });
        }
      };
    });
    

    You'd attach it to body like so:

    <body should-scroll>