0

The stated aim is fairly straight forward and easy to do in static pages with JQuery. On the document ready event, you'd have something like

$('.fadeIn').fadeIn();

Which would give you a nice, clean way of applying an animation effect to any elements that required it on your UI.

Enter angular and my first experience with it (very n00b here). I would like to apply the concept above but trigger it once angular has figured out and done all it's necessary rendering. I need this on most views but only on elements that I want to animate.

Researching this, it seems that the angular way of doing this is via a directive which lead me to this post on how to hook into angular at various points in the life cycle.

My angular setup is pretty basic;

HTML

<div ng-app="profile" class="fadeIn">
    Some content
</div>

Controller

(function (app) {
    var controller = function () {
    };
    app.controller("menuController", [controller]);
})(angular.module("dashboard"));

app.js

(function (appName) {

    var app = angular.module(appName, ["ngRoute", "ui.bootstrap"]);

    app.config(['$locationProvider', function ($locationProvider) {
        $locationProvider.hashPrefix("");
    }]);

    var routeConfig = function ($routeProvider) {
        $routeProvider.when("/",
                {
                    templateUrl: "app/menu/menu.html",
                    controller: "menuController"
                });

        $routeProvider.otherwise({ redirectTo: "/" });
    }

    app.config(routeConfig);
    console.log("app started");
}("dashboard"));

With that setup in mind, my approach to apply my original concept and hook into angular's directives is as follows;

myAnimate.js

angular.module("profile", []).directive('directive',
    function($timeout) {
        return {
            restrict: 'A',
            link: function(scope, element, attr) {
                $timeout(function() {
                    SetupAnimations();
                });
            }
        }
    });

function SetupAnimations() {
    $(".fadeIn").fadeIn();
}

When I put a breakpoint on the return statement, it's never hit. However, the angular.module() call is hit and runs without error.

I know I can hook into the controller's initialization using $rootScope but this means that I have to initialize for every controller. I'd like to be able to apply it globally across the application.

I'm pretty sure I'm either missing something very simple or have approached this from the wrong angle entirely.

10
  • You haven't included your profile module as dependency in the main app module Commented Nov 7, 2017 at 12:43
  • @charlietfl how do I go about doing that? Commented Nov 7, 2017 at 12:44
  • Same way you injected ngRoute Commented Nov 7, 2017 at 12:44
  • @charlietfl so change the module config to angular.module(appName, ["ngRoute", "ui.bootstrap", "profile"])? I just tried that and no effect. Commented Nov 7, 2017 at 12:48
  • OK now the directive is looking for an element <directive></directive> that doesn't exist. The restrict:'E' refers to element based on name of the directive Commented Nov 7, 2017 at 12:52

1 Answer 1

0

After a bit of tinkering and help from charlietfl, I managed to get to the source of the issue. There were a few misconfigurations there that resulted in the behaviour described.

The primary one was that appName was undefined and it not being used in any of the angular markup that was in the app (I'm working on legacy code) and this made hooking a directive in tricky. Knowing that, I moved the code for myAnimation.js into the app.js like so;

(function (appName) {
    // appName here results in "undefined" error message but angular hooks in all the same
    var app = angular.module(appName, ["ngRoute", "ui.bootstrap"]);
    app.config(['$locationProvider', function ($locationProvider) {
        $locationProvider.hashPrefix("");
    }]);

    // the moved in directive here where it can attach to the app correctly
    app.directive('animate',
        function () {
            return {
                restrict: 'A',
                link: function (scope, element, attr) {
                    SetupAnimations();
                }
            }
        });

    //...remainder of logic in here unchanged
}("dashboard"));

function SetupAnimations() {
    $(".fadeIn").fadeIn();
}

My HTML now looks like;

<div animate class="fadeIn"></div>

And the animation works just fine.

EDIT

I've refined further as per the angular documentation on directives such that my directive setup hooks into how the directives work rather than leveraging jQuery for the animation hookup. The SetupAnimations() method is removed and the directive reduced to the following;

app.directive('fadeIn',
    function () {
        return {
            restrict: 'A',
            link: function(scope, element) {
                element.fadeIn();
            }
        }
    });

Which leaves my HTML markup like (note the hyphen - read the documentation linked to above);

<div fade-In></div>
Sign up to request clarification or add additional context in comments.

2 Comments

Also note that element is a jQuery object when jQuery.js is in page before angular.js. So element.fadeIn() is same as $(element).fadeIn()
@charlietfl, that's good to know. I was taking an "assume nothing" approach but I'll clean that up

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.