Trong Lam Phan
Trong Lam Phan

Reputation: 2412

Angularjs ccreate @keyframes animation CSS in directive

I want to create @keyframes animation CSS in directive function of Angularjs. The problem is that i can't create it before. I need a variable of scope to create this keyframes.

app.directive("myCSSDiv", function() {
    var css = "@keyframes myAnimation {";
    var nb_msg = ??? // Here i want to get a variable like $scope.nb_msg but i don't know how to get it
    if(nb_msg == 2) {
        css += "0%, 100% {left: 0px}";
        css += "30%, 60% {left: -100px}";
    } else if(nb_msg == 3) {
        css += "0%, 100% {left: 0px}";
        css += "15%, 50% {left: -100px}";
        css += "60%, 85% {left: -200px}";
    } else if(...) {
        ...
    }
    return {
        restrict: "E",
        template: css
    }
});

Any suggestions? Thanks!

Upvotes: 0

Views: 1185

Answers (1)

gkalpak
gkalpak

Reputation: 48211

The scope is available (among other places) in the linking function of the directive.
In that case, although you can access the current scope, it is a good practice to isolate the directive's scope and pass the value as a parameter.

If you want to use the value in the template, you can access it through an attribute:

app.directive('myCssDiv', function () {
    function buildAnimationCss(nb_msg) {
        var css = '@keyframes myAnimation {';
        switch (nb_msg) {
            case 2:
                css += "0%, 100% {left: 0px}";
                css += "30%, 60% {left: -100px}";
                break;
            case 3:
                css += "0%, 100% {left: 0px}";
                css += "15%, 50% {left: -100px}";
                css += "60%, 85% {left: -200px}";
                break;
            case ...:
                ...
                break;
        }
        return css;
    }

    return {
        restrict: 'E',
        template: function (tElem, tAttrs) {
            return buildAnimationCss(parseInt(tAttrs.message));
        }
    }
});

Then use it like this:

<my-css-div message="{{nb_msg}}"></my-css-div>

UPDATE:

If you expect nb_msg to change or to be asynchronously initialized at a later point, you should use the linking function and $watch over it:

app.directive('myCssDiv', function () {
    function buildAnimationCss(nb_msg) {...}

    return {
        restrict: 'E',
        scope: {
            message: '='
        },
        link: function myCssDivPostLink(scope, elem, attrs) {
            scope.$watch('message', function (newValue) {
                var nb_msg = parseInt(newValue);   // unless it is already an integer...
                if (!isNaN(nb_msg)) {
                    elem.html(buildAnimationCss(nb_msg));
                }
            });
        }
    }
});

Then use it like this:

<my-css-div message="nb_msg"></my-css-div>

Upvotes: 2

Related Questions