Reputation: 3117
I have an angular-js app with some controllers that shouldn't be shown initially. They flash on the screen despite my use of ng-cloak. The problem seems to be that compile gets called and removes the ng-cloak directives and class, this makes the controllers contents visible even though it shouldn't be because ng-show is false.
If I pause js execution in ng-cloak's compile method I can see the elements appear as the ng-cloak directive is removed. If I pause js execution in the controller (for example on "$scope.visible = false;") I can see the controller stays visible on the page. The controller is then invisible again as it should be sometime later in loading.
How can I prevent this flashing? Why doesn't ng-cloak pay respect to ng-show?
index.html:
<div ng-cloak class="ng-cloak" ng-controller="RoomsController" ng-show="visible">
<h1>This flashes, it can be seen if we set a breakpoint in the controller js, or after the ng-cloak directive's compile method in angular.js</h1>
</div>
app.js:
app.controller('RoomsController', ['$scope',
function ($scope) {
$scope.visible = false;
}
]);
Upvotes: 9
Views: 6254
Reputation: 2685
After a lot messing around I managed to "fix" this by adding ng-hide
class to the element, while removing ng-cloak
completely:
<div class="ng-hide" ng-controller="RoomsController" ng-show="visible">
<h1>This flashes, it can be seen if we set a breakpoint in the controller js, or after the ng-cloak directive's compile method in angular.js</h1>
</div>
This hides the element initially. Angular then removes the ng-hide
class when processing the ng-show
directive.
Upvotes: 2
Reputation: 35900
I had a similar problem with ngCloak in IE mobile. The simplest solution I came up with is similar to some of the other answers, but I use ng-show instead, and without any extra $scope
variables:
<div class="ng-hide" ng-show="true">
{{mydata}}
</div>
The solution requires that you add the ng-hide
class and ng-show="true"
. This ensures that the element will only be visible after the ng-show
directive is linked.
Upvotes: 14
Reputation: 359
use a ng-hide in the class, JS will take it off or set it again even if its there but till JS kicks in it can sit there and use CSS to hide your div
<div data-ng-controller="RoomsController">
<div ng-cloak class="ng-cloak ng-hide" data-ng-if="visible" >
Some text
</div>
</div>
Upvotes: 0
Reputation: 2767
I've reproduced your issue and the thing that worked for me was to create inner div
and use ng-if
directive instead of ng-show
. I hope it helps.
<div data-ng-controller="RoomsController">
<div ng-cloak class="ng-cloak" data-ng-if="visible" >
Some text
</div>
</div>
Upvotes: 2
Reputation: 35478
ngCloak
directive hides the related elements until the end compile
process. This is useful for hiding {{ someBinding }}
stuff, and probably nothing else. The actual linking and binding in the linking
process.
To prevent flashing of an element, it shouldn't be there until the application bootstraps itself. You can take a look at ngInclude
for simple widgets, and ngView
for bigger, complex things.
Upvotes: 1