web-dev-qa-db-fra.com

Angularjs - éléments ng-cloak/ng-show clignotent

J'ai un problème dans angular.js avec directive/class ng-cloak ou ng-show.

Chrome fonctionne bien, mais Firefox fait clignoter des éléments avec ng-cloak ou ng-show. À mon humble avis, cela est dû à la conversion du ng-cloak/ng-show en style="display: none;". cacher?

Exemple:

<ul ng-show="foo != null" ng-cloak>..</ul>
225
MelkorNemesis

Bien que la documentation ne le mentionne pas, il ne sera peut-être pas suffisant d'ajouter la règle display: none; à votre CSS. Si vous chargez angular.js dans le corps ou que les modèles ne sont pas compilés assez tôt, utilisez la directive ng-cloak et incluez ce qui suit dans votre code CSS:

/* 
  Allow angular.js to be loaded in body, hiding cloaked elements until 
  templates compile.  The !important is important given that there may be 
  other selectors that are more specific or come later and might alter display.  
 */
[ng\:cloak], [ng-cloak], .ng-cloak {
  display: none !important;
}

Comme mentionné dans le commentaire, le !important est important. Par exemple, si vous avez le balisage suivant

<ul class="nav">
  <li><a href="/foo" ng-cloak>{{bar}}</a></li>
</ul>

et vous utilisez bootstrap.css, le sélecteur suivant est plus spécifique pour votre élément ng-cloak 'ed

.nav > li > a {
  display: block;
}

Ainsi, si vous incluez une règle avec simplement display: none;, la règle de Bootstrap sera prioritaire et la variable display sera définie sur block;.

383
Tim Schaub

Comme mentionné dans la documentation , vous devez ajouter une règle à votre CSS pour la masquer en fonction de l'attribut ng-cloak:

[ng\:cloak], [ng-cloak], .ng-cloak {
    display: none;
}

Nous utilisons des astuces similaires sur le site "Built with Angular", dont vous pouvez voir la source sur Github: https://github.com/angular/builtwith.angularjs.org

J'espère que cela pourra aider!

46
btford

Assurez-vous que AngularJS est inclus dans la head du HTML. Voir ngCloak doc :

Pour un meilleur résultat, le script angular.js doit être chargé dans la tête section du fichier html; sinon, la règle css (ci-dessus) doit être inclus dans la feuille de style externe de l'application.

32
drozzy

Je n'ai jamais eu beaucoup de chance avec ngCloak. Je continue de scintiller malgré tout ce qui est mentionné ci-dessus. Le seul moyen sûr d'éviter de feuilleter est de placer votre contenu dans un modèle et d'inclure le modèle. Dans un SPA, le seul code HTML qui sera évalué avant d’être compilé par Angular est votre page index.html principale. 

Prenez tout ce qui est à l’intérieur du corps et collez-le dans un fichier séparé, puis:

<ng-include src="'views/indexMain.html'"></ng-include>

Vous ne devriez jamais obtenir un tel scintillement car Angular compilera le modèle avant de l'ajouter au DOM.

27
Matt Hughes

ng Bind et ng Bind Template sont des alternatives qui ne nécessitent pas de CSS:

<div ng-show="foo != null" ng-cloak>{{name}}</div>  <!-- requires CSS -->
<div ng-show="foo != null" ng-bind="name"></div>
<div ng-show="foo != null" ng-bind-template="name = {{name}}"></div>
22
Mark Rajcok

En plus de la réponse acceptée si vous utilisez une autre méthode de déclenchement de ng-cloak ...

Vous voudrez peut-être aussi ajouter quelques spécificités supplémentaires à votre CSS/LESS:

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

J'ai eu un problème similaire et j'ai découvert que si vous avez une classe qui contient des transitions, l'élément clignotera. J'ai essayé d'ajouter ng-cloak sans succès, mais en supprimant la transition, le bouton cessait de clignoter.

J'utilise un cadre ionique et le contour du bouton a cette transition

.button-outline {
  -webkit-transition: opacity .1s;
  transition: opacity .1s;
}

Remplacez simplement la classe pour supprimer la transition et le bouton cessera de clignoter.

Mettre à jour

De nouveau sur ionic, il y a un scintillement lorsque vous utilisez ng-show/ng-hide. L'ajout du CSS suivant le résout:

.ng-hide-add,
.ng-hide-remove {
  display: none !important;
}

Source: http://forum.ionicframework.com/t/beta-14-ng-hide-show/14270/9

15
Seb Fanals

J'ai eu un problème où un <div ng-show="expression"> serait initialement visible pendant une fraction de seconde, même si "expression" était initialement faux, avant que la directive ng-show ne puisse s'exécuter.

La solution que j'ai utilisée consistait à ajouter manuellement la classe "ng-hide", comme dans <div ng-show="expression" ng-hide>, afin de m'assurer qu'elle a été initialement masquée. La directive ng-show ajoutera/supprimera ensuite la classe ng-hide si nécessaire.

9
metamatt

Essayez de éteignez le Firebug . Je suis serieux. Cela aide dans mon cas.

Appliquez la réponse acceptée et assurez-vous que Firebug dans votre Firefox est activé désactivé : appuyez sur F12 puis désactivez Firebug pour cette page - petit bouton dans le coin supérieur droit.

7
CoperNick

En fait, deux problèmes distincts peuvent être à l’origine du problème de scintillement et vous pourriez être confronté à l’un ou l’autre de ces problèmes. 

Problème 1: ng-cloak est appliqué trop tard

Ce problème est résolu comme indiqué dans de nombreuses réponses sur cette page est de s’assurer que AngularJS est chargé dans la tête. Voir ngCloak doc :

Pour un meilleur résultat, le script angular.js doit être chargé dans la tête section du fichier html; sinon, la règle css (ci-dessus) doit être inclus dans la feuille de style externe de l'application.

Problème 2: ng-cloak est retiré trop tôt 

Ce problème est plus susceptible de se produire lorsque vous avez beaucoup de CSS sur votre page avec des règles en cascade les unes sur les autres et que les couches plus profondes de CSS apparaissent avant que la couche supérieure ne soit appliquée. 

Les solutions jQuery dans les réponses impliquant l'ajout de style="display:none" à votre élément résolvent ce problème tant que le style est supprimé suffisamment tard (en fait, ces solutions résolvent les deux problèmes). Cependant, si vous préférez ne pas ajouter de styles directement à votre code HTML, vous pouvez obtenir les mêmes résultats avec ng-show.

En commençant par l'exemple de la question:

<ul ng-show="foo != null" ng-cloak>..</ul>

Ajoutez une règle ng-show supplémentaire à votre élément:

<ul ng-show="isPageFullyLoaded && (foo != null)" ng-cloak>..</ul>

(Vous devez garder ng-cloak pour éviter le problème 1).

Ensuite, dans votre application, définissez isPageFullyLoaded:

app.run(['$rootScope', function ($rootScope) {
    $rootScope.$safeApply = function (fn) {
        $rootScope.isPageFullyLoaded = true;
    }
}]);

Sachez que selon ce que vous faites, app.run peut ne pas être le meilleur endroit pour définir isPageFullyLoaded. L'important est de s'assurer que isPageFullyLoaded est défini sur true après que tout ce que vous ne voulez pas scintiller soit prêt à être révélé à l'utilisateur.

Il semble que Problème 1 soit le problème rencontré par le PO, mais d’autres trouvent que la solution ne fonctionne pas ou ne fonctionne que partiellement car c’est plutôt le Problème 2 qui l’a frappé.

Remarque importante: Assurez-vous de bien appliquer les solutions à la fois pour que ng-cloak soit appliqué trop tard ET soit éliminé trop tôt. Résoudre un seul de ces problèmes peut ne pas soulager les symptômes. 

6
Andrew Downes

Nous avons rencontré ce problème dans notre société et l'avons résolu en ajoutant "display: none" au style CSS pour ces éléments ng-show scintillants. Nous n'avions pas du tout besoin d'utiliser ng-cloak. Contrairement à d'autres dans ce fil, nous avons rencontré ce problème dans Safari, mais pas dans Firefox ni dans Chrome - probablement en raison de le bug de repeinte paresseux de Safari dans iOS7 .

4
Jake McGuire

Pour ce que cela vaut, j'ai eu un problème similaire ng-cloak ne fonctionne pas. Il peut être intéressant de vérifier votre application/site avec le cache activé pour réutiliser les fichiers source pour voir si cela aide.

Avec mon run-in avec le scintillement, je testais avec DevTools ouvert et le cache désactivé. Laisser le panneau fermé avec la mise en cache activée a résolu mon problème.

3
mrdazm

Garder les déclarations ci-dessous dans la balise head a résolu ce problème

<style type="text/css">
    [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
    display: none !important;
}
</style>

documentation officielle

3
Saikiran K

Je ne pouvais pas utiliser aucune de ces méthodes, alors j'ai finalement fait ce qui suit. Pour l'élément que vous voulez initialement masqué:

<div <!--...--> style="display: none;" ng-style="style">

Ensuite, dans votre contrôleur, ajoutez ceci en haut ou près du haut:

$scope.style = { display: 'block' };

De cette façon, l'élément est initialement masqué et ne s'affiche que lorsque le code du contrôleur est réellement exécuté.

Vous pouvez adapter l'emplacement à vos besoins, en ajoutant peut-être un peu de logique. Dans mon cas, je bascule vers un chemin de connexion si je ne suis pas actuellement connecté et que je ne voulais pas que mon interface scintille auparavant. J'ai donc défini $scope.style après le contrôle de connexion.

3
shawkinaw

J'ai essayé la solution ng-cloak ci-dessus mais il y a toujours des problèmes intermittents avec Firefox . La seule solution de contournement qui fonctionne pour moi est de retarder le chargement du formulaire jusqu'à ce que Angular soit complètement chargé.

J'ai simplement ajouté ng-init dans l'application et utilisé ng-if du côté du formulaire pour vérifier si la variable que j'ai définie est déjà chargée.

<div ng-app="myApp" ng-init="loaded='yes'"> 
   <form ng-if="loaded.length > 0">
      <!--all my elements here-->
   </form>
</div>
2
java25

vous feriez mieux de faire référence à un document angulaire, car la version [1.4.9] a une mise à jour plus bas qui lui permet de supporter la directive data-ng-cloak 

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

Il vaut mieux utiliser ng-if au lieu de ng-show. ng-if supprime et recrée complètement l'élément dans le DOM et permet d'éviter le clignotement de ng-shows.

2
alexey

AS de la discussion ci-dessus 

[ng-cloak] {
                display: none;
            }

est le moyen idéal pour résoudre le problème. 

1
Dinesh Jain

Aucune des solutions énumérées ci-dessus n'a fonctionné pour moi. J'ai alors décidé d'examiner la fonction réelle et de réaliser que lorsque «$ scope.watch» était déclenché, il s'agissait de mettre une valeur dans le champ du nom, ce qui n'était pas censé être le cas. Donc, dans le code, je mis et oldValue et newValue puis

$scope.$watch('model.value', function(newValue, oldValue) {
if (newValue !== oldValue) {
validateValue(newValue);
}
});

Dans ce cas, essentiellement lorsque scope.watch est activé, AngularJS surveille les modifications apportées à la variable de nom (model.value).

1
D.Adelakun

En plus d’autres réponses, si vous trouvez que le flash de code de modèle est toujours actif, il est probable que vos scripts se trouvent au bas de la page, ce qui signifie que la directive ng-cloak ne fonctionnera pas. Vous pouvez déplacer vos scripts vers la tête ou créer une règle CSS.

Les docs disent "Pour un meilleur résultat, le script angular.js doit être chargé dans la section head du document html; sinon, la règle css ci-dessus doit être incluse dans la feuille de style externe de l'application."

Maintenant, il ne faut pas que ce soit une feuille de style externe mais juste un élément dans la tête.

<style type="text/css">
  .ng-cloak {
    display: none !important;
  }
</style>

source: https://docs.angularjs.org/api/ng/directive/ngCloak

1
Elijah Lynn

J'ai essayé toutes les réponses ci-dessus et rien n'a fonctionné. Utiliser ionic pour développer une application hybride et essayait de faire en sorte que le message d'erreur ne scintille pas. J'ai fini par résoudre mon problème en ajoutant une classe ng-hide à mon élément. Ma div a déjà ng-show pour afficher l'élément en cas d'erreur. Ajouter ng-hide permet de ne pas afficher la div avant le chargement de angular. Aucune ng-cape ou ajout angulaire à la tête nécessaire.

1
gyleg5

J'ai essayé toutes les solutions publiées ici et j'ai encore clignoté dans Firefox.

Si cela aide quelqu'un, je le résous en ajoutant style="display: none;" à la div principale content, puis en utilisant jQuery (je l'utilisais déjà sur la page) $('#main-div-id').show(); une fois que tout a été chargé après l'obtention des données du serveur;

1
hipnosis

J'utilise ng-show dans une directive pour afficher et masquer les popups.

<div class="..." ng-show="showPopup">

Rien de ce qui précède n'a fonctionné pour moi, et utiliser ng-if au lieu de ng-show serait excessif. Cela impliquerait la suppression et l'ajout de tout le contenu contextuel dans le DOM à chaque clic. Au lieu de cela, j'ai ajouté un ng-if dans le même élément pour m'assurer qu'il ne s'affiche pas au chargement du document:

<div class="..." ng-show="showPopup" ng-if="popupReady">

Ensuite, j'ai ajouté l'initialisation au contrôleur responsable de cette directive avec un délai d'attente:

$timeout(function () {
    $scope.popupReady = true;
});

De cette façon, j'ai éliminé le problème de scintillement et évité l'opération coûteuse d'insertion DOM à chaque clic. Cela s'est fait au détriment de l'utilisation de deux variables d'étendue dans le même but au lieu d'une, mais jusqu'à présent, c'est la meilleure option.

1
downhand

En fait, j'ai trouvé la suggestion de Web Log de Rick Strahl mon problème a été parfaitement résolu (car j'avais toujours l'étrange problème avec ng-cloak clignotant brutalement {{code}}, par exemple, surtout lorsque j'utilisais Firebug):

L'option nucléaire: masquer le contenu manuellement

Le meilleur choix est d’utiliser le CSS explicite, les éléments suivants ne devraient donc plus être nécessaires. Mais je le mentionnerai ici, car il explique comment masquer/afficher le contenu manuellement en charge pour d’autres frameworks ou dans vos propres modèles basés sur des balises.

Avant de comprendre que je pouvais explicitement intégrer le style CSS à la page, j’avais essayé de comprendre pourquoi ng-cloak ne faisait pas son travail. Après avoir perdu une heure à arriver nulle part, j'ai finalement décidé de simplement masquer et montrer manuellement le conteneur. L'idée est simple: commencez par masquer le conteneur, puis affichez-le une fois qu'Angular a effectué son traitement initial et supprimé le balisage du modèle de la page.

Vous pouvez masquer manuellement le contenu et le rendre visible une fois que Angular a pris le contrôle. Pour ce faire j'ai utilisé:

<div id="mainContainer" class="mainContainer boxshadow"
    ng-app="app" style="display:none">

Notez le style d'affichage: aucun qui masque explicitement l'élément initialement sur la page.

Ensuite, une fois que Angular a exécuté son initialisation et traité efficacement le modèle de balisage sur la page, vous pouvez afficher le contenu. Pour Angular, cet événement «prêt» est la fonction app.run ():

app.run( function ($rootScope, $location, cellService) {        
    $("#mainContainer").show();
    …
});

Cela supprime efficacement le style d'affichage: aucun et le contenu s'affiche. Au moment où app.run () se déclenche, le DOM est prêt à être affiché avec des données remplies ou au moins des données vides - Angular a obtenu le contrôle.

1
Campbeln

J'ai personnellement décidé d'utiliser l'attribut ng-class plutôt que le ng-show. J'ai eu beaucoup plus de succès dans cette voie, surtout pour les fenêtres contextuelles qui ne sont pas toujours affichées par défaut. 

Quel était auparavant <div class="options-modal" ng-show="showOptions"></div>

est maintenant: <div class="options-modal" ng-class="{'show': isPrintModalShown}">

avec CSS pour la classe options-modal étant display: none par défaut. La classe show contient le CSS display:block.

0

Je voudrais envelopper le <ul> avec un <div ng-cloak>

0
Dan Doyon

Essayé ng-cloak mais toujours bref clignote. Le code ci-dessous les débarrasse complètement.

<body style="display:none;" ng-style="{'display':'block'}">
0
Abu Abdullah