Question

I am building a AngularJs app with RequireJs and trying to make a animation like: https://egghead.io/lessons/angularjs-animating-the-angular-way/

I load all vendor JS Files with HeadJs.

Iam facing 2 problems: 1) When I click on

  • foo
  • or
  • bar
  • , the directive seems unable to detect value in animate-when changes except the very first time when page loads.

    2) Even the time directive response to value in animate-when, the animation is not triggered. I check it added a class to element. Why no animation? I tried to put TweenMax command to directive directly and animation shows which TweenMax is working.

    This problem tortured me for the last few hours. Developing with AngularJs somehow frustured me semdomly although it is very powerful. Hope someone can help me out. Thank you so much.

    Here is part of the HTML:

    <section data-ng-controller="HomePageController">
        <nav>
            <ul>
                <li ng-click="a=true; b=false">foo</li>
                <li ng-click="b=true; a=false">bar</li>
            </ul>
            <hr>
            <section animate-when="{{ showA }}" data-animate-class="showExpand"></section>
            <section animate-when="{{ showB }}" data-animate-class="showExpand"></section>
        </nav>
    </section>
    

    Both showA and showB are attributes in HomePageController:

    $scope.showA = true;
    $scope.showB = false;
    

    Module:

    (function (define, angular) {
        "use strict";
    
        define(['controllers/HomePageController',
        'directives/animateWhen',
        'animations/showExpand'
        ],
        function (HomePageController, animateWhen, showExpand) {
        var moduleName = "page";
    
        angular.module(moduleName, ["ngAnimate"])
        .controller("HomePageController", HomePageController)
        .animation(".showExpand", showExpand)
        .directive("animateWhen", animateWhen);
        return moduleName;
        });
    
    }(define, angular));
    

    showExpand Animation:

    (function (define) {
        define([''], function () {
            var showExpand = function () {
                return {
                    addClass: function(element, className){
                        //not running
                        console.log("startAdding");
                        TweenMax.to(element, 1, {opacity:0});
                    },
                    removeClass: function(element, className){
                        //not running either
                        console.log("startRemoving");
                        TweenMax.to(element, 1, {opacity:0});
                    }
                }
            };
    
            return [ showExpand ];
        });
    }(define));
    

    And here is the animateWhen directive:

    (function (define) {
        define([''], function () {
            var animateWhen = function ($animate) {
                return function(scope, element, attrs){
                    scope.$watch(attrs.watch, function(value){
                        if(value){
                            console.log("add"); //run once only when page is load
                            TweenMax.to(element, 1, {opacity:1});
                            $animate.addClass(element, attrs.animateClass);
                        } else {
                            console.log("remove"); //same, run once only
                            TweenMax.to(element, 1, {opacity:0});
                            $animate.removeClass(element, attrs.animateClass);
                        }
                    }, true);
                }
            };
    
            return [ "$animate", animateWhen ];
        });
    }(define));
    
    Was it helpful?

    Solution

    For watching directive attributes you need to use attrs.$observe, since there is no watch property in the scope (you don't even have an isolate scope).

    Try:

    attrs.$observe("watch", function(value){
    
    };
    

    instead.

    Licensed under: CC-BY-SA with attribution
    Not affiliated with StackOverflow
    scroll top