How to prevent element show before AngularJS initialized( ng-show )
2 alternatives to completely avoid the problem:
- ngBind
<span ng-bind="expression_without_braces"></span>
It is preferable to use
ngBind
instead of{{ expression }}
if a template is momentarily displayed by the browser in its raw state before AngularJS compiles it. SincengBind
is an element attribute, it makes the bindings invisible to the user while the page is loading.
- use
ui-router
to keep HTML in separate files, which will be loaded/parsed/injected only when needed and only when the controller is initialized.
Here's the hello world tutorial modified to use a separate HTML file:
// helloworld.js
var myApp = angular.module('helloworld', ['ui.router']);
myApp.config(function($stateProvider) {
var helloState = {
name: 'hello',
url: '/hello',
templateUrl: 'helloworld.html'
}
$stateProvider.state(helloState);
});
<!-- helloworld.html -->
<h3>hello world!</h3>
<!-- index.html -->
<html>
<head>
<script src="lib/angular.js"></script>
<script src="lib/angular-ui-router.js"></script>
<script src="helloworld.js"></script>
</head>
<body ng-app="helloworld">
<a ui-sref="hello" ui-sref-active="active">Hello</a>
<ui-view></ui-view>
</body>
</html>
In case you want to just avoid showing something till it's ready to be shown (some data has been loaded from the backend perhaps) then it's better to use ng-if
. Ofcourse it works the same with ng-show
. But the advantage of using ng-if
is that you delay the creation of the extra DOM until it needs to be shown and as a result you improve the intial page loading time.
Here is an example:
var myApp = angular.module('myApp', []);
myApp.controller("myController", function ($scope, $timeout) {
$scope.isLoading = false;
$scope.data = null;
simAsync();
//simulate async task like http request
function simAsync() {
//loadind data has started
$scope.isLoading = true;
$timeout(function () {
$scope.data = [{
"firstname": "Sims",
"lastname": "Wilkerson"
}, {
"firstname": "Kelli",
"lastname": "Vazquez"
}, {
"firstname": "Mcdonald",
"lastname": "Byrd"
}, {
"firstname": "Taylor",
"lastname": "Frost"
}, {
"firstname": "Merle",
"lastname": "Adkins"
}, {
"firstname": "Garrett",
"lastname": "Hood"
}];
//the data has loaded
$scope.isLoading = false;
}, 1500);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
</div>
Unless you want to show a loader, ng-cloak should be your solution.
Official documentation on ng-cloak
If you still have the issue, you may try to add the css to hide element with ng-cloak inside your html to be sure the browser has it in time.
If you do that, choose on way to add the ng-cloak. For example add it as class:
<div ng-show="condition" class="ng-cloak">...</div>
And add this into your html head tag:
<style> .ng-cloak { display: none !important; } </style>