0

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!

1 Answer 1

2

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>
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much, only one problem remains, that nb_msg is NaN. I think that the template function works before the controller function where i set this variable "nb_msg". I must set nb_msg in controller function because i need some parameters like $http, $scope.
@blck: In that case you should probably use a link function (and possibly $watch over nb_msg) then use element.html(...) to change the content of the custom element. But without more info, I can't be sure it will work. Edit: Take a look at my updated answer - maybe it helps.

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.