2

I'm trying to show an arrow icon to be used as "go to top" button, but only after some scrolling done by the user. The code used to work great using jquery, but I'm having hard time to achieve the same effect using angular. At the moment, the arrow is always seen in the bottom right corner of the screen.

JSfiddle here.

JS:

var myApp = angular.module('app',[]);

myApp.controller('ctrl', ['$scope', function($scope) {
     //detect scroll
    $(window).scroll(function (event) {
    var scroll = $(window).scrollTop();
        console.log(scroll);
        if(scroll>500 || scroll==undefined){
            $scope.showUpArrow = false;
        }else{
            $scope.showUpArrow = true;
        }
    });
}]);

HTML:

<div ng-app="app">
  <div ng-controller="ctrl">
    <div ng-hide="showUpArrow" id="goUp-cont">
      <a href="#top"><i class="fa fa-arrow-up fa-4x" id="goUp"></i></a>
    </div>
  </div>
</div>
1

2 Answers 2

3

You gonna need to manually $apply() (or $digest()) your scope, as you are in a jquery handler, so basically outside of angular cycle.

myApp.controller('ctrl', ['$scope', function($scope) {
     //detect scroll
    $(window).scroll(function (event) {
    var scroll = $(window).scrollTop();
        console.log(scroll);
        if(scroll>500 || scroll==undefined){
            $scope.showUpArrow = false;
        }else{
            $scope.showUpArrow = true;
        }
        **$scope.$apply();**
    });
}]);

should basically fix your problem

To avoid expensive digestion cycles on each scroll event when they are, most of the time, useless, you should also check the initial value of showUpArrow, triggering the digest cycle only if the value changed :

myApp.controller('ctrl', ['$scope', function($scope) {
     //detect scroll
    $(window).scroll(function (event) {
    var scroll = $(window).scrollTop();
    var oldState = $scope.showUpArrow;
        console.log(scroll);
        if(scroll>500 || scroll==undefined){
            $scope.showUpArrow = false;
        }else{
            $scope.showUpArrow = true;
        }
        if($scope.showUpArrow !== oldState) {
            $scope.$apply();
        }
    });
}]);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer. Only one thing, the arrow is seen when the page first loads, why is so? showUpArrow is first evaluated to false.
@undroid, it is first evaluated to false because you have ng-hide="showUpArrow" in your HTML. It should be ng-show="showUpArrow", i updated a fiddle with those modifications
2

A call $scope.apply() is missing:

$(window).scroll(function (event) {
    var scroll = $(window).scrollTop();
    console.log(scroll);
    if(scroll>500 || scroll==undefined){
        $scope.showUpArrow = false;
    }else{
        $scope.showUpArrow = true;
    }
    $scope.$apply();
});

See it working on updated fiddle

More info on why you have to do this: here for example

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.