Angularjs - Ng-Cloak/Ng-Show Elements Blink

Angularjs - ng-cloak/ng-show elements blink

Though the documentation doesn't mention it, it might not be enough to add the display: none; rule to your CSS. In cases where you are loading angular.js in the body or templates aren't compiled soon enough, use the ng-cloak directive and include the following in your CSS:

/* 
Allow angular.js to be loaded in body, hiding cloaked elements until
templates compile. The !important is important given that there may be
other selectors that are more specific or come later and might alter display.
*/
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none !important;
}

As mentioned in the comment, the !important is important. For example, if you have the following markup

<ul class="nav">
<li><a href="/foo" ng-cloak>{{bar}}</a></li>
</ul>

and you happen to be using bootstrap.css, the following selector is more specific for your ng-cloak'ed element

.nav > li > a {
display: block;
}

So if you include a rule with simply display: none;, Bootstrap's rule will take precedence and the display will be set to block, so you'll see the flicker before the template compiles.

Ng-Show causing flicker

I have found the issue. I had loaded the navigation as a template in each view, so when I changed routes, it was causing a flicker on the ng-show item. Moving the template into my index page resolved the issue, as it is loaded once. Example:

 <%--Container for HTML, inclusive of AngularJS App and responsive aspects--%>
<div class="container">

<%--Include top menu--%>
<div data-ng-include="'../Templates/topmenu.html'"></div>

<%--Load Angular Views--%>
<div data-ng-view></div>

<%--Footer of page. Could be an include as well--%>
<hr>
<footer></footer>
</div>

ng-cloak has not effect whatsoever on blinking Angular code

Did you add a style for hiding [ng-cloak] atrribute?

When this css rule is loaded by the browser, all html elements (including their children) that are tagged with the ngCloak directive are hidden. When Angular encounters this directive during the compilation of the template it deletes the ngCloak element attribute, making the compiled element visible.

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}

How does ng-cloak work?

Angular will interpolate the bindings at the end of the $digest cycle so that all of the other modifications have already completed. If they were processed earlier, a directive might later change the binding or scope and cause the DOM to be out-of-date.

You can decorate the $interpolate service so that you can log when Angular interpolates a binding:

.config(function($provide){
$provide.decorator("$interpolate", function($delegate){
function wrap() {
var x = $delegate.apply(this, arguments);
if (x) {
var binding = arguments[0];
return function() {
var result = x.apply(this, arguments);
console.log('binding:', binding, result);
return result;
}
}
}
angular.extend(wrap, $delegate);
return wrap;
});
})

You can then see that all of the directives have been processed and finally, the $interpolate service is called and the DOM is modified accordingly.

Click here for live demo.

AngularJS shows model text before compilation despite ng-cloak

This is not an answer you are looking for, but there is a good practice to write

<span ng-bind="data"> </span> 

(so no {{data}} blinking).

  • ng-cloak styles already on the page. Look in the header of rendered page with angular app.

  • you can do something like:

<body ng-show="loaded"></body> and set scope.loaded = true in controller, after data is loaded.



Related Topics



Leave a reply



Submit