How to correctly use ng-cloak directive?
JavascriptAngularjsAngularjs DirectiveNgcloakJavascript Problem Overview
Somehow, ng-cloak in AngularJS doesn't work. I want to hide {{ }} while loading the page. Because it looks awful.
<!DOCTYPE html>
<html lang="en" ng-app>
<head>
<meta charset="UTF-8">
<title>Angular Sample</title>
</head>
<body ng-model="isShow" ng-init="isShow=true">
<p ng-show="isShow"><span ng-cloak>{{ isShow }}</span></p>
<p ng-show="!isShow"><span ng-cloak>{{ isShow }}</span></p>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</body>
</html>
Javascript Solutions
Solution 1 - Javascript
Add this css from here
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
and use either the class name or attribute on your parent div or anywhere you have defined your app.
eg:
<div ng-app="Random" class="ng-cloak">
</div>
Solution 2 - Javascript
From the Angular docs:
> For the best result, the angular.js
script must be loaded in the head section of the html document; alternatively, the css rule above must be included in the external stylesheet of the application.
Solution 3 - Javascript
You have to specify these rules in your CSS:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
Solution 4 - Javascript
Using ngBind should eliminate that as well (I develop in SharePoint sometimes and ngCloak won't work).
AngularJS Docs:
> It is preferable to use ngBind instead of {{ expression }} if a > template is momentarily displayed by the browser in its raw state > before Angular compiles it. Since ngBind is an element attribute, it > makes the bindings invisible to the user while the page is loading. > > An alternative solution to this problem would be using the ngCloak > directive.
JS:
var app = angular.module('test', []);
app.controller('testCtrl', ['$scope', function($scope) {
$scope.test = "Hello World";
}]);
HTML:
<html ng-app="test">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="testCtrl">
<h1 ng-bind="test"></h1>
</body>
</html>
Solution 5 - Javascript
Add below in your css file:-
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
Solution 6 - Javascript
In my case, I figured that my troubles was dues to pending ajax requests. Ng-cloak probably works for static content, but if a template depends an ajax data then this is thus rendered before receiving the ajax response.
To avoid it I define a directive :
angu
mymodule
.directive("ajaxCloak", ['$interval', '$http', function ($interval, $http) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
let stop = $interval(() => {
if ($http.pendingRequests.length === 0) {
$interval.cancel(stop);
attrs.$set("ajaxCloak", undefined);
element.removeClass("ajax-cloak");
}
}, 100);
}
};
}]);
With a bit of CSS :
[ajax-cloak], [data-ajax-cloak], [x-ajax-cloak], .ajax-cloak {
display: none !important;
}
Then in your main HTML file:
<div ui-view data-ajax-cloak></div>
Note: this isn't as sophisticated as ng-cloak as this is a global cloack, it hides everything until all requests are finished.
Solution 7 - Javascript
My solution I think i tried all of above suggestions but nothing worked. Some uses ng-include but it seems a little bit to much, further it could be scary with the inner scope that gets created. So it tried it by using style and ng-style. In my affected main div.
<div class="container" style="display:hidden;" ng-style="loaded">
Then I set the scope variable loaded in my base controller.
$scope.loaded ={display:'block'};Still got all those {{ }}. Weird when display sets to block only when angularjs has loaded. Then I noticed that I had the firefox f12 developer console running. Its doing stuff. Stupid me
Solution 8 - Javascript
From angular 1.3 onwards, you must specify a name for ng-app attribute for it to work.
<html lang="en" ng-app="myApp">
IN your JS:
angular.module("myApp",[])
This will make the angular to bootstrap.
But for the current situation, as you are loading angular at the bottom of the page, it's taking time to load. So the css required for the ng-cloak
is not available yet.
Either move the js
to the tag or load the specific CSS code to your CSS to make it work.
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
Solution 9 - Javascript
I have tried all of the answers above and a lot beyond, with no help. My (large) page would flicker on each load. My solution was to add this just after body tag:
<div style="display:flex" opacity=0>
<status-progress></status-progress>
<h3>Loading... </h3>
</div>
and to wrap everything in the page:
<div class="loaded" style="opacity: 0" opacity=1> ... </div>
directive:
app.directive('opacity', opacity);
function opacity($timeout) {
return {
link: function (scope, element, attrs) {
var value = attrs.opacity;
$timeout(function () {
element[0].style.opacity = value;
},500);
}
}
}
To make the page appear "smoother", the stylesheet:
.loaded{
transition: opacity 1s ease-in-out;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
}
This way, you see "Loading" for 1sec, while everything is getting ready.
Solution 10 - Javascript
Since none of these answers gave me the desired result, I accomplished what I wanted by creating a directive very similar to ng-cloak
but wrapping the code in a $timeout
so that it will wait until the end of the $digest
cycle to remove the cloaking attribute and/or class. This was the only way I was able to truly hide the {{}}
bindings in the browser.
angular.directive('myCloak', function($timeout) {
return {
restrict: 'A',
compile: function (element, attr) {
$timeout(function () {
attr.$set('myCloak', undefined);
element.removeClass('my-cloak');
});
}
};
});
And don't forget, you will have to add a custom css rule for this new attribute / class:
[my\:cloak], [my-cloak], [data-my-cloak], [x-my-cloak], .my-cloak, .x-my-cloak {
display: none !important;
}
Solution 11 - Javascript
Using the fix recommended here works for me...
https://github.com/opitzconsulting/jquery-mobile-angular-adapter/issues/167
CSS:
.my-cloak {
display: none !important;
}
JS:
$scope.$on('$viewContentLoaded', function(){
$('.my-cloak').removeClass('my-cloak');
});
HTML:
div(class="my-cloak")
Solution 12 - Javascript
Use ngBind when ng-cloak is not available.
<p ng-show="!isShow" ng-bind="isShow"></p>