1

I have a hidden component in a directive and yet when the page is loaded, the hidden element appears for the duration of the animation, which should only be triggered when the component's model is set to visible.

In this example I set the component to ng-hide="true" permanently, and when the page is loaded it still appears for half a second. In my real program the directive is much more complicated, so I placed the template in its own file, the problem doesn't appear if I just put it in a string.

I tried adding style="display:none" to the template's content, but then it doesn't react to model changes later.

<html ng-app="myApp">
<head>
    <style>
    .overlay {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: black;

        transition: all linear 0.5s;
    }
    .overlay.ng-hide {
        opacity: 0;
    }
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.18/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.18/angular-animate.min.js"></script>
    <script>
    angular.module("myApp", ['ngAnimate'])
        .directive("overlay", function() {
            return {
                replace: true,
                templateUrl: "overlay.html"
            };
        });
</script>
</head>
<body>
    <overlay></overlay>
</body>
</html>

overlay.html:

<div class="overlay" ng-hide="true"></div>

Plunker: http://plnkr.co/edit/tYLkGwPJtFPxH2ES6qIe?p=preview

modi
  • 13
  • 3

2 Answers2

0

You can add a link function that adds a display: none property to the overlay element temporarily and then removed afterwards when the ng-hide directives kicks in by watching the ng-hide initial value and then removing the display: none property and deregistering the watcher.

Something like this: FORKED PLUNKER

    .directive("overlay", function() {
        return {
            templateUrl: "overlay.html",
            link: function(scope, elem, attr) {
              elem.css('display', 'none');
              var dereg = scope.$watch(attr.ngHide, function(value) {
                elem.css('display', '');
                dereg();
              });
            }
        };
    });

Note that I have removed the replace property, it is depreciated in angular 3.0 and above. Reference

ryeballar
  • 29,658
  • 10
  • 65
  • 74
0

You could do the opposite using ng-class instead. Switch your CSS so the overlay only shows when you add a class show:

.overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: black;
    opacity: 0;

    transition: all linear 0.5s;
}
.overlay.show {
    opacity: 1;
}

Then just use the ng-class directive on your overlay, change the false value to whatever expression you have in mind.

<div class="overlay" ng-class="{show : false}"></div>

Here's the Forked Plunker

Dan-Nolan
  • 6,594
  • 4
  • 27
  • 32