ChatGPT解决这个技术问题 Extra ChatGPT

Prevent double curly brace notation from displaying momentarily before angular.js compiles/interpolates document

It seems to be primarily an issue in IE when there is a number of images/scripts to load, there can be a good amount of time where the literal {{stringExpression}} in the markup are displayed, then disappear once angular is done with it's compilation/interpolation of the document.

Is there a common reason why this would happen which would indicate I'm doing something generally wrong, or is there a known way to prevent this?

The above was the right solution

C
Community

I think that you are looking for the ngCloak directive: https://docs.angularjs.org/api/ng/directive/ngCloak

From the documentation:

The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display. The directive can be applied to the 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


To avoid the raw Angular HTML code, is ngCloak widespread/best practice? It seems like a no brainer, but I'm not experienced in AngularJS.
I don't think this will work if you load all scripts at the end of the body.
Aaah, wait, nvm, LOAS's answer is the solution if you load scripts last. Use the .ng-cloak class.
Load angularjs script at the <head> section of your html for ngCloak to be effective.
I can confirm it works perfectly if I load angular.js in the <head> section of my page.
A
Andrew Joslin

Also, you can use <span ng-bind="hello"></span> instead of {{hello}}.

http://jsfiddle.net/4LhN9/34/


One feature about ng-bind that is sometimes overlooked is that you can specify text to display while Angular is loading: loading.... "loading..." will appear, then be replaced once myScopeProperty is defined.
@MarkRajcok: thanks for the tip! I had no idea. That's very simple and elegant and solves a problem I myself have had.
If you need multiple expressions, use ngBindTemplate. E.g., loading...
You can also do {{hello || 'loading...'}}
@AndyJoslin Nice. With this approach, the angular js script needs to be in the head, as opposed to the bottom of the page, to avoid the {{}} expression from flashing when the page loads.
L
LOAS

To improve the effectiveness of class='ng-cloak' approach when scripts are loaded last, make sure the following css is loaded in the head of the document:

.ng-cloak { display:none; }

Adding !important is not bad idea also.
Wouldn't visibility: hidden be better?
@eomeroff, but !important is a CSS hack (bad thing) to promote a style to be selected, right? It breaks the CSS selector rules.
IMHO this is one of the cases !important was introduced for.
@Mark I would guess that "visibility: hidden" would still render the space needed for the template markup, whereas "display:none" doesn't render anything at all. With only the visibility hidden, any outer elements may suddenly collapse to the true inner size, instead of growing to size from nothing. I suppose it's whatever one prefers. :)
B
Bennett McElwee

Just add the cloaking CSS to the head of the page or to one of your CSS files:

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

Then you can use the ngCloak directive according to normal Angular practice, and it will work even before Angular itself is loaded.

This is exactly what Angular does: the code at the end of angular.js adds the above CSS rules to the head of the page.


+1 I came up with the [ngcloak] selector myself, but this is more complete.
Awesome answer! I load Angular at the end of my body, so ngCloak isn't available and it still flashes the {{}}. This fixed it.
N
Nathan Senevirathne

In your css add folllowing

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

And then in you code you can add ng-cloak directive. For example,

<div ng-cloak>
   Welcome {{data.name}}
</div>

Thats it!


M
Martin Schüller

You also can use ng-attr-src="{{variable}}" instead of src="{{variable}}" and the attribute will only be generated once the compiler compiled the templates. This is mentioned here in the documentation: https://docs.angularjs.org/guide/directive#-ngattr-attribute-bindings


J
Jaison James

I agree with @pkozlowski.opensource answer, but ng-clock class did't work for me for using with ng-repeat. so I would like to recommend you to use class for simple delimiter expression like {{name}} and ngCloak directive for ng-repeat.

<div class="ng-cloak">{{name}}<div>

and

<li ng-repeat="item in items" ng-cloak>{{item.name}}<li>

Thanks for noticing me the mistake