Empêcher la notation à double accolade de s'afficher momentanément avant que angular.js compile / interpole le document

298

Cela semble être principalement un problème dans IE quand il y a un certain nombre d'images / scripts à charger, il peut y avoir une bonne quantité de temps où le littéral {{stringExpression}}dans le balisage est affiché, puis disparaît une fois que l'angulaire est fait avec sa compilation / interpolation de le document.

Y a-t-il une raison commune pour laquelle cela se produirait qui indiquerait que je fais quelque chose de mal en général, ou existe-t-il un moyen connu d'empêcher cela?

JeremyWeir
la source
Ce qui précède était la bonne solution
Edmund Rojas

Réponses:

283

Je pense que vous recherchez la ngCloakdirective: https://docs.angularjs.org/api/ng/directive/ngCloak

De la documentation:

La directive ngCloak est utilisée pour empêcher le modèle HTML angulaire d'être brièvement affiché par le navigateur dans sa forme brute (non compilée) pendant le chargement de votre application. Utilisez cette directive pour éviter l'effet de scintillement indésirable provoqué par l'affichage du modèle html.

La directive peut être appliquée à l' <body>élément, mais l'utilisation préférée consiste à appliquer plusieurs ngCloak directives à de petites portions de la page pour permettre un rendu progressif de la vue du navigateur

pkozlowski.opensource
la source
1
Pour éviter le code HTML angulaire brut, la pratique est-elle ngCloakrépandue / recommandée? Cela semble être une évidence, mais je ne suis pas expérimenté dans AngularJS.
Kevin Meredith
32
Je ne pense pas que cela fonctionnera si vous chargez tous les scripts à la fin du corps.
trusktr
8
Aaah, attendez, nvm, la réponse de LOAS est la solution si vous chargez les scripts en dernier. Utilisez la classe .ng-cloak.
trusktr
3
Chargez le script angularjs dans la <head>section de votre html pour ngCloakêtre efficace.
Mustafa
1
Je peux confirmer que cela fonctionne parfaitement si je charge angular.jsdans la <head>section de ma page.
Aron Lorincz
197

Vous pouvez également utiliser à la <span ng-bind="hello"></span>place de {{hello}}.

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

Andrew Joslin
la source
94
Une caractéristique de ng-bind qui est parfois négligée est que vous pouvez spécifier le texte à afficher pendant le chargement d'Angular: <span ng-bind = "myScopeProperty"> loading ... </span>. "loading ..." apparaîtra, puis sera remplacé une fois myScopeProperty défini.
Mark Rajcok
@MarkRajcok: merci pour l'astuce! Je n'en avais aucune idée. C'est très simple et élégant et résout un problème que j'ai moi-même eu.
Jim Raden
9
Si vous avez besoin de plusieurs expressions, utilisez ngBindTemplate. Par exemple, <span ng-bind-template = "{{scopeProperty1}} {{scopeProperty2}}"> chargement ... </span>
Mark Rajcok
27
Vous pouvez également faire {{bonjour || 'chargement ...'}}
Andrew Joslin
5
@AndyJoslin Nice. Avec cette approche, le script angulaire js doit être dans la tête, par opposition au bas de la page, pour éviter que l'expression {{}} ne clignote lorsque la page se charge.
s_t_e_v_e
51

Pour améliorer l'efficacité de l'approche class = 'ng-cloak' lorsque les scripts sont chargés en dernier, assurez-vous que le CSS suivant est chargé dans la tête du document:

.ng-cloak { display:none; }
LOAS
la source
4
Ajouter! Important n'est pas non plus une mauvaise idée.
eomeroff
12
Ce ne serait pas visibility: hiddenmieux?
mpen
2
@eomeroff, mais !importantest-ce un hack CSS (mauvaise chose) pour promouvoir un style à sélectionner, non? Il casse les règles du sélecteur CSS.
Kevin Meredith
5
À mon humble avis, c'est l'un des cas! Important a été introduit pour.
lex82
3
@Mark Je suppose que "visibilité: cachée" rendrait toujours l'espace nécessaire pour le balisage du modèle, alors que "affichage: aucun" ne rend rien du tout. Avec seulement la visibilité cachée, tous les éléments extérieurs peuvent soudainement s'effondrer à la vraie taille intérieure, au lieu de grandir à partir de rien. Je suppose que c'est ce que l'on préfère. :)
James Wilkins
40

Ajoutez simplement le CSS de masquage en tête de page ou à l'un de vos fichiers CSS:

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

Ensuite, vous pouvez utiliser le directive ngCloak selon la pratique Angular normale, et cela fonctionnera même avant le chargement d'Angular lui-même.

C'est exactement ce que fait Angular: le code à la fin de angular.js ajoute les règles CSS ci-dessus en tête de page.

Bennett McElwee
la source
+1 Je suis moi-même venu avec le [ngcloak]sélecteur, mais c'est plus complet.
Pierre Henry
1
Réponse géniale! Je charge Angular à la fin de mon corps, donc ngCloak n'est pas disponible et il clignote toujours le {{}}. Cela l'a corrigé.
Scottie
21

Dans votre CSS, ajoutez ce qui suit

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

Et puis dans votre code, vous pouvez ajouter la directive ng-cloak. Par exemple,

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

C'est tout!

Nathan Senevirathne
la source
3

Je suis d'accord avec la réponse @ pkozlowski.opensource, mais la classe ng-clock n'a pas fonctionné pour moi pour une utilisation avec ng-repeat. Je voudrais donc vous recommander d'utiliser la classe pour une expression de délimiteur simple comme {{name}} et la directive ngCloak pour ng-repeat.

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

et

<li ng-repeat="item in items" ng-cloak>{{item.name}}<li>
Jaison
la source
Merci de m'avoir remarqué l'erreur
Jaison