JeroenE JeroenE - 24 days ago 15
AngularJS Question

block ng-animate when going to the same state

Currently we've a problem in our project using

ng-animate
.
We've got two states, lets name them for now: State 1 and State 2. Both have their state name as a div class.
<div class="state1">
.

Now state1 should slide up to the top, and slide2 should slide in from the bottom. This is working fine when switching between slide1 and slide2. However, if a user clicks on another button that moves to state1 (when being on state1) then only the content should change and no animation should be done.

Currently we use:
.state1.ng-leave { }
for the leaving animation on the state1 div, and
.state2.ng-enter { }
on the entering state. As you can see, when I'm on state1 and clicking on a button that will give another page with state1 then still the
.state1.ng-leave { }
will get called and the animation will be done.

Anyone got a solution for us? The
ng-leave {}
for state1 should only be triggered as soon as state2 is entering.

State1/State2 flow

Things we've tried:


  • We tried to add something to
    state('home.state1', { }
    to block the
    ng-animation
    for state1. When you enter state1, we never need an animation. We didn't find the solution using this. Probably there is something we can add to
    onExit:
    what we didn't try?

  • We also tried to work with ng-animate in the div.


Preview In this plnkr I have made an example what is going wrong. If you click "state1", you can see that the page is sliding up, but we don't want that. We just want to "refresh" the page so you just get the page without animation. If you click state2 then the animation should be done (just like the example shows). I also added a button on the state2 page that shows how the page should load when going from state1 to state1. Please check my example below:

https://plnkr.co/edit/zaFcZFOEtCybRuXobYl0?p=preview

Answer

Well here is the issue that i see. Any anchor tag with a # is taken as a redirect by angular so what it does as your route '/' is set to home page, angular redirects on that anchor click to home page and as the home page has a ng-leave animation applied. It does the animation.

In order to achieve what you want you just need to remove the # from the href and keep it empty as href="". Now that does not make sense as to why you would want a empty anchor but that gives you a dirty result but a result none the less (Hehe).

Now assuming you are wanting this to be done is to use the # anchor to navigate to a tag/element within the same page using hash linking. You can use the controller $anchorScroll() for it.

Example code:

yourapp.controller('yourControllername', function($scope, $location, $anchorScroll) {
  $scope.scrollTo = function(id) {
  $location.hash(id);
  $anchorScroll();
  } 
});

<a ng-click="scrollTo('sectionA')">Foo</a>

<div id="sectionA">Here you are</div>

Hope this helps.

[Edit]

Ok after knowing your full requirement now based on your comment to this answer. I think i have come up with another solution to fit you needs. Its not perfect but it works until we find a good solution. Here is what you need to do (Keeping the sample code you shared in mind).

a) We make a new page and call it page-other.html. This will have same links buttons as home page with state 1 navigating to home using href="#" in anchor and state2 navigating to about as before. Just change the <h2>Home</h2> to <h2>Home- Other</h2> just to keep track where we are.

b) Add the page into the routeprovider but give it the same controller as mainController as follows:

.when('/other', {
        templateUrl: 'page-other.html',
        controller: 'mainController'
    })

c) Add the class page-no-animate in the css setting it just like home page with background color etc. except for the animation part will be none as follows:

.page-no-animate { background:#00D0BC; color:#00907c; }

.page-no-animate.ng-enter,
.page-no-animate.ng-leave,
.page-no-animate.ng-animate {
   animation:none 0s;
   -webkit-animation: none 0s;
}

d) Change your mainController code to as follows. What it does is it has a function named gotoOther which sets the pageClass to page-no-animate and redirects to the other page using $location.path("/other"). After this funtion we have if-else condition that check on which location we are to apply appropriate animation or no-animation pageClass value as we dont want the other page to animate when we click the state 1 again to come back:

animateApp.controller('mainController', ['$scope', '$location', 
function($scope, $location) {
    $scope.gotoOther = function () {
        $scope.pageClass = 'page-no-animate';
        $location.path("other");
    };
    if ($location.path() == "/other")
    {
        $scope.pageClass = 'page-no-animate';
    }
    else
    {
        $scope.pageClass = 'page-home';
    }
}]);

e) In you page-home.html, in the "State1" anchor tag: empty the href attribute and add the ng-click attribute to call the gotoOther function we created in the controller as follows

<a href="" ng-click="gotoOther()" class="btn btn-success btn-lg">State1</a>
Comments