Where exactly to use ngCloak in existing app - angularjs

We have an AngularJS app (not a SPA). We face this problem where some part of uncompiled template is displayed for brief moments, so I am applying ngCloak directive to the app.
I'm not sure of where exactly should this directive be used - every single, small element or large sections (or somewhere else). What I'm currently doing is throttling connection via Chrome dev tools to a very slow speed and then checking which parts of template show up in raw state. But I feel this is not a very deterministic approach.
So I would like to know the where exactly to use ngCloak.
Thank You.

Applying ngCloak to every small element is certainly the wrong way to go.
You would typically want to apply it either to large sections, or to the entire portion of your page that uses Angular. The objective is to hide these parts of the page until Angular is ready to use.
This is what the official documentation says:
The directive can be applied to the <body> element, but the preferred usage is to apply multiple ngCloak directives to small portions of the page to permit progressive rendering of the browser view.
If you don't want your users to be looking at blank space, you can show a loading animation until Angular finishes loading. You can do this by giving the element an ng-show="false" directive:
<img src='/images/loading.gif' ng-show='false' />

Please add following code into head section of index.html
<style>
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
</style>
And you can add same code into your css file
Thanks

Without [ng-cloak] when you run your application before angularJs rendering you will see some angular codes like "{{myngModel}} or something like this, when you put [ng-cloak] in your project on run you didn't see those codes until rendering complete .
[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
display: none !important;
}
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>app</title>
</head>
<body ng-cloak>
</body>
</html>

Related

For AngularJS, if we use ngCloak, shouldn't we add one CSS style to our HTML file to hide the element?

What if we use ng-cloak, but the angular script is loading slowly, or if the user has turned off JavaScript, then wouldn't the user still see {{ a + b }} or anything we wanted to hide?
Would it be a good practice then, if we add
<style>
[ng-cloak] { display: none !important }
</style>
to our HTML file's header section? Or would there be other CSS style that might be appropriate to add if we are using AngularJS and the Internet connection might be slow or if the user has turned off JavaScript?
If you are loading angular.js in the head section of your page, then you should not have to add any css yourself for ng-cloak to work properly. Angular adds these styles itself when it loads, and since this happens in the head section, these styles are applied before the browser evaluates the body of your page and renders any content.
However, if you are loading angular asynchronously with a script loader, then you do need to add the styles manually (preferably in a stylesheet or style block loaded in the head of your page).
From the docs:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
I'm not totally sure I understand the question, but yes, I believe what you are saying makes sense.
ng-cloak is a bit different from other directives, because its only job is to remove itself. Angular does not apply any special styling to that attribute. It just removes it.
That means, for example, you could apply styling to make unloaded Angular elements have a background color, instead of being invisible. I don't know why you'd do that, but that's something to remember--it's just a boring old attribute until Angular removes it.
Behavior of loading CSS files is up to the browser, so it's probably fair to put a style tag in the head, but that's just like any other CSS resources--you rarely want elements loading without styles, and browsers are pretty good about avoiding that. I often like to put it in the head just for good measure, but I can understand someone not wanting to do that. But you definitely need it somewhere.
If you have JavaScript disabled, or before Angular loads, it's just like any other attribute:
[ng-cloak]{
display: none
}
<div ng-cloak>
Where am I?
</div>
But once Angular loads (no matter how long it takes to set up, simulated here by a one-second timer):
window.setTimeout(function() {
$("[ng-cloak]").removeAttr("ng-cloak");
}, 1000);
[ng-cloak] {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-cloak>
Here I am!
</div>

Able to see a preview of hidden elements before page load in Firefox

So on my webpage, I have several elements that should be hidden on initial page load (like error messages) but should be shown if they satisfy certain conditions. I'm using Angular JS.
The problem is that although it works perfectly in Chrome, in Firefox, you can briefly see a preview of the hidden elements which then disappear after the page has fully loaded. I want to avoid this.
<span id="invalidDate" ng-show="invalidDateEntered==true" class="alert">Invalid Date Format</span>
So I can see this alert Invalid Date Format before the page has loaded fully in Firefox but it disappears soon after. I've tried using ng-init to prevent this, but it hasn't helped.
<span id="invalidDate" ng-init="invalidDateEntered=false" ng-show="invalidDateEntered==true" class="alert">Invalid Date Format</span>
Any ideas as to how I can fix this?
Use ng-cloak on elements:-
<span id="invalidDate" ng-cloak ng-show="invalidDateEntered==true" class="alert">Invalid Date Format</span>
In Css:-
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}

How can I avoid a delay when ng-class is applied to the body tag?

I'm using a class name on the <body> tag of a page to define whether the contents of a page is zoomed.
<body 'ng-class'=> "Preferences.zoomed()">
The default setting for Preferences.zoomed() is false and so the page loads in a non zoomed state.
Unfortunately though there seems to be a brief delay in between the page loading and ng-class getting evaluated. This means that when the page loads (and is set to zoom) it constantly (albeit briefly) flips from the non-zoomed state to the zoomed state making things flicker unpleasantly.
I presume this is because Angular evaluates after the dom loads...
I'm guessing that this momentary state occurs because the angular isn't parsed and evaluated until after the dom completes loading. Hence the page loads with zoom=false and then flicks to zoom-true.
How can I force ng-class to be evaluated as it loads into the page?
Is there any way to force Angular to evaluate this expression as the element itself loads and to avoid this flickering?
Please have a look here https://docs.angularjs.org/api/ng/directive/ngCloak
<body 'ng-class'=> "Preferences.zoomed()" ng-cloak="">
css:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}

ng-cloak doesn't help for angular ui-router for hiding elements while template parsing

I'm using angular ui-router.
I want to show something if <div ng-show="total > 0">
While the template is downloaded and shown immediately we can see a flicker of the div, before the controller loads $scope.total =.
One would think that $scope.total is undefined in the beginning hence the div would be hidden, but I think the template isn't yet parsed, it's just shown raw. I tried using ng-cloak but it doesn't seem to help. Ngcloak is supposed to be used while angular is booting up, but I'm using ui-router so the angular stack is already loaded. How can I hide my elements on the template without resorting to ui-router resolves?
I'm using angular 1.2.8 and ui-router 0.2.7.
PLease check this one, seems like solution to your problem.
https://stackoverflow.com/a/13276214/801354
You'll have to apply this style to get ng-cloak working
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
None of the solutions worked for me. The only solution is the following:
In each controller, add:
$scope.$on('$viewContentLoaded', function () {
$scope.completed = true;
});
and in the html of each view , add ng-if="completed" to the topmost element. For example:
<div ng-if="completed">
Note: the problem is restricted to firefox and ui-router. There, ng-cloak is ignored and there is no css workaround. The only solution that worked for me is the one I gave above.

Alternative to ng-show/-hide or how to load only relevant section of DOM

When using ng-show/-hide, the content included in those blocks initially displays on the user screen. Only after few milliseconds (after angular.js has loaded and executed) does the right block show up in ng-show.
Is there a better way than ng-show/-hide to load only the relevant section of data into the DOM?
The problem with ng-view is that I can have only one on the page, so I have to toggle the behavior of many sections of the DOM based on the current state.
To avoid the "flash of uncompiled content", use ng-bind instead of {{}} or use ng-cloak:
<span ng-cloak ng-show="show">Hello, {{name}}!</span>
If you use ng-cloak, and you do not load Angular.js in the head section of your HTML, you will need to add this to your CSS file, and ensure it loads at the top of your page:
[ng\:cloak], [ng-cloak], .ng-cloak { display: none; }
Note that you only need to use these directives on your initial page. Content that is pulled in later (e.g., via ng-include, ng-view, etc.) will be compiled by Angular before the browser renders.
Is there a better way to load data other than ng-show / hide, in which only the relevant section is loaded into the DOM.
Some alternatives to ng-show/ng-hide are ng-include, ng-switch and (since v1.1.5) ng-if:
<div ng-include src="someModelPropertySetToThePartialYouWantToLoadRightNow"></div>
See also https://stackoverflow.com/a/12584774/215945 for an example of ng-switch working together with ng-include.
Note that ng-switch and ng-if add/remove DOM elements, whereas ng-show/hide only alters the CSS (if that matters to you).
I used the ng-cloak trick and it doesn't seem to work that well. Following the Angular documentation I added the following to my CSS and that does work:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
See: http://docs.angularjs.org/api/ng.directive:ngCloak
Per Mark Rajcok's fine answer, here's a CodePen showing ng-show, ng-switch, and ng-if in action, so you can compare the approaches, and see differences in how the conditional content is actually rendered.
Note that some people feel that ng-show is a little faster than ng-switch and ng-if for file-based templates. But you can use $templateCache to preload your templates at bootstrap time, reducing or eliminating that advantage. Using ng-switch and ng-if, you no longer have to deal with hidden conditional content being in the DOM when it's not needed, and prevent expressions on that content being evaluated by Angular at inopportune times. That saves you processing resources you don't need to waste, and avoids errors that can be thrown when something's evaluated prematurely.

Resources