Angularjs ccreate @keyframes анимация CSS в директиве

#javascript #css #angularjs #angularjs-directive #css-animations

#javascript #css #angularjs #angularjs-директива #css-анимация

Вопрос:

Я хочу создать анимацию @keyframes CSS в директивной функции Angularjs. Проблема в том, что я не могу создать его раньше. Мне нужна переменная области видимости для создания этих ключевых кадров.

 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
    }
});
 

Есть предложения? Спасибо!

Ответ №1:

Область действия доступна (среди прочих мест) в функции связывания директивы.
В этом случае, хотя вы можете получить доступ к текущей области видимости, рекомендуется изолировать область действия директивы и передать значение в качестве параметра.

Если вы хотите использовать значение в шаблоне, вы можете получить к нему доступ через атрибут:

 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));
        }
    }
});
 

Затем используйте его следующим образом:

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

Обновить:

Если вы ожидаете nb_msg изменения или асинхронной инициализации на более позднем этапе, вам следует использовать функцию связывания и $watch поверх нее:

 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));
                }
            });
        }
    }
});
 

Затем используйте его следующим образом:

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

Комментарии:

1. Большое вам спасибо, остается только одна проблема, что nb_msg — это NaN . Я думаю, что функция шаблона работает до функции контроллера, где я устанавливаю эту переменную «nb_msg». Я должен установить nb_msg в функции контроллера, потому что мне нужны некоторые параметры, такие как $ http, $ scope.

2. @blck: В этом случае вам, вероятно, следует использовать функцию ссылки (и, возможно $watch , более nb_msg ), а затем использовать element.html(...) для изменения содержимого пользовательского элемента. Но без дополнительной информации я не могу быть уверен, что это сработает. Редактировать : Взгляните на мой обновленный ответ — возможно, это поможет.