wake-up-neo.com

Angularjs - ng-cloak/ng-show Elemente blinken

Ich habe ein Problem in angle.js mit der Direktive/Klasse ng-cloak oder ng-show.

Chrome funktioniert gut, aber Firefox verursacht ein Blinzeln der Elemente mit ng-cloak oder ng-show____. IMHO wird durch das Konvertieren von ng-cloak/ng-show in style="display: none;" verursacht. Wahrscheinlich ist der Firefox-Javascript-Compiler etwas langsamer, und die Elemente erscheinen dann eine Weile verbergen?

Beispiel:

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

Obwohl die Dokumentation dies nicht erwähnt, reicht es möglicherweise nicht aus, die display: none;-Regel in Ihr CSS aufzunehmen. Wenn Sie angle.js in den Body laden oder Vorlagen nicht früh genug kompiliert werden, verwenden Sie die ng-cloak-Direktive und Folgendes in Ihr 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;
}

Wie im Kommentar erwähnt, ist der !important wichtig. Zum Beispiel, wenn Sie das folgende Markup haben

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

wenn Sie bootstrap.css verwenden, ist der folgende Selektor spezifischer für Ihr ng-cloak ed-Element

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

Wenn Sie also eine Regel in display: none; einfügen, hat die Bootstrap-Regel Vorrang, und display wird auf block gesetzt. Sie sehen also das Flimmern, bevor die Vorlage kompiliert wird.

383
Tim Schaub

Als in der Dokumentation erwähnt sollten Sie Ihrem CSS eine Regel hinzufügen, um es basierend auf dem ng-cloak-Attribut auszublenden:

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

Wir verwenden ähnliche Tricks auf der Website "Built with Angular", die Sie auf Github als Quelle anzeigen können: https://github.com/angular/builtwith.angularjs.org

Hoffentlich hilft das!

46
btford

Stellen Sie sicher, dass AngularJS in der head des HTML-Codes enthalten ist. Siehe ngCloak doc :

Um das beste Ergebnis zu erzielen, muss das angle.js-Skript in den Kopf geladen werden Abschnitt der HTML-Datei; alternativ muss die css-Regel (oben) .__ sein. im externen Stylesheet der Anwendung enthalten.

32
drozzy

Ich habe mit ngCloak noch nie viel Glück gehabt. Ich flackere trotz allem, was oben erwähnt wurde. Der einzige todsichere Weg, um das Schnippen zu vermeiden, besteht darin, Ihren Inhalt in eine Vorlage zu packen und die Vorlage hinzuzufügen. In einem SPA wird Ihre einzige index.html-Seite der einzige HTML-Code, der ausgewertet wird, bevor er von Angular kompiliert wird. 

Nehmen Sie einfach alles in den Körper und stecken Sie es in eine separate Datei und dann:

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

Sie sollten niemals auf diese Weise flackern, da Angular die Vorlage kompiliert, bevor Sie sie dem DOM hinzufügen.

27
Matt Hughes

ng Bind und ng Bind Template sind Alternativen, die kein CSS erfordern:

<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

Zusätzlich zur akzeptierten Antwort, wenn Sie eine alternative Methode zum Auslösen von ng-cloak verwenden ...

Sie können auch zusätzliche Besonderheiten zu Ihrem CSS/LESS hinzufügen:

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

Ich hatte ein ähnliches Problem und fand heraus, dass das Element blinken wird, wenn Sie über eine Klasse verfügen, die Übergänge enthält. Ich habe versucht, ng-cloak ohne Erfolg hinzuzufügen, aber durch Entfernen des Übergangs hörte die Schaltfläche auf zu blinken.

Ich verwende ein ionisches Gerüst und die Schaltfläche-Kontur hat diesen Übergang

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

Überschreiben Sie einfach die Klasse, um den Übergang zu entfernen, und die Schaltfläche hört auf zu blinken.

Update

Bei ionic gibt es wieder ein Flimmern, wenn ng-show/ng-hide verwendet wird. Durch das Hinzufügen des folgenden CSS wird es behoben:

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

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

15
Seb Fanals

Ich hatte ein Problem, bei dem ein <div ng-show="expression"> zunächst für einen Sekundenbruchteil sichtbar war, obwohl "expression" anfangs falsch war, bevor die ng-show -Direktive eine Chance hatte, auszuführen.

Die von mir verwendete Lösung bestand darin, die Klasse "ng-hide" wie in <div ng-show="expression" ng-hide> manuell hinzuzufügen, um sicherzustellen, dass sie ursprünglich ausgeblendet wurde. Die ng-show-Direktive fügt die ng-hide-Klasse anschließend hinzu bzw. entfernt sie.

9
metamatt

Versuchen Sie, den Firebug auszuschalten. Ich meine es ernst. Das hilft in meinem Fall.

Übernehmen Sie die akzeptierte Antwort und stellen Sie sicher, dass Firebug in Ihrem Firefox aktiviert ist Aus: Drücken Sie die Taste F12, und deaktivieren Sie Firebug für diese Seite - kleine Schaltfläche in der rechten oberen Ecke.

7
CoperNick

Es gibt zwei verschiedene Probleme, die das Flimmern verursachen können, und Sie könnten entweder einem oder beiden davon gegenüberstehen. 

Problem 1: ng-mantel wird zu spät angelegt

Dieses Problem wird wie in vielen Antworten auf dieser Seite beschrieben behoben. Es soll sichergestellt werden, dass AngularJS in den Kopf geladen wird. Siehe ngCloak doc :

Um das beste Ergebnis zu erzielen, muss das angle.js-Skript in den Kopf geladen werden Abschnitt der HTML-Datei; alternativ muss die css-Regel (oben) .__ sein. im externen Stylesheet der Anwendung enthalten.

Problem 2: ng-mantel wird zu früh entfernt 

Dieses Problem tritt höchstwahrscheinlich auf, wenn sich auf Ihrer Seite viel CSS befindet, wobei die Regeln übereinander liegen und die tieferen CSS-Ebenen aufblinken, bevor die oberste Ebene angewendet wird. 

Die jQuery-Lösungen in Antworten, die das Hinzufügen von style="display:none" zu Ihrem Element beinhalten, lösen dieses Problem, solange der Stil zu spät entfernt wird (tatsächlich lösen diese Lösungen beide Probleme). Wenn Sie jedoch vorziehen, Stile nicht direkt in Ihren HTML-Code einzufügen, können Sie mit ng-show dieselben Ergebnisse erzielen.

Beginnen wir mit dem Beispiel aus der Frage:

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

Fügen Sie Ihrem Element eine zusätzliche ng-show-Regel hinzu:

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

(Sie müssen ng-cloak beibehalten, um Problem 1 zu vermeiden).

Dann in Ihrem app.run set isPageFullyLoaded:

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

Beachten Sie, dass app.run, je nachdem, was Sie genau tun, isPageFullyLoaded am besten geeignet ist. Das Wichtigste ist, sicherzustellen, dass isPageFullyLoaded auf true gesetzt wird, nachdem das, was Sie nicht flackern möchten, dem Benutzer angezeigt werden kann.

Es klingt wie Problem 1 ist das Problem, das das OP trifft, aber andere finden, dass die Lösung nicht funktioniert oder nur teilweise funktioniert, weil sie stattdessen oder ebenfalls auf Problem 2 treffen.

Wichtiger Hinweis: Stellen Sie sicher, dass Sie Lösungen auf beide zu spät aufgetragenen Ng-Cloak anwenden UND bald entfernen. Das Lösen nur eines dieser Probleme kann die Symptome nicht lindern. 

6
Andrew Downes

Wir sind auf dieses Problem in unserem Unternehmen gestoßen und haben das CSS-Styling für diese flackernden ng-show-Elemente mit "display: none" versehen. Wir mussten überhaupt keinen Ng-Mantel verwenden. Im Gegensatz zu anderen Themen in diesem Thread ist dieses Problem in Safari aufgetreten, jedoch nicht in Firefox oder Chrome - möglicherweise aufgrund von Safari 's Lazy Repaint Bug in iOS7 .

4
Jake McGuire

Für das, was es wert ist, hatte ich ein ähnliches Problem, das nicht funktionierte. Es kann sich lohnen, Ihre App/Site mit aktiviertem Cache zu überprüfen, um die Quelldateien erneut zu verwenden, um zu sehen, ob dies hilfreich ist.

Bei meinem Run-In mit Flimmern testete ich mit geöffneten DevTools und deaktiviertem Cache. Wenn das Panel mit aktivierter Zwischenspeicherung geschlossen wurde, wurde mein Problem behoben.

3
mrdazm

Dieses Problem wurde behoben, indem die folgenden Anweisungen im head-Tag beibehalten wurden

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

offizielle Dokumentation

3
Saikiran K

Ich konnte keine dieser Methoden zum Laufen bringen, also tat ich schließlich Folgendes. Für das Element, das Sie zunächst ausblenden möchten:

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

Dann fügen Sie dies in Ihrem Controller oben oder oben hinzu:

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

Auf diese Weise wird das Element zunächst ausgeblendet und zeigt nur an, wann der Controller-Code tatsächlich ausgeführt wurde.

Sie können die Platzierung an Ihre Bedürfnisse anpassen, indem Sie einige Logik hinzufügen. In meinem Fall wechsle ich zu einem Anmeldepfad, wenn er derzeit nicht angemeldet ist, und wollte nicht, dass meine Benutzeroberfläche zuvor flackert. Daher habe ich $scope.style nach der angemeldeten Überprüfung festgelegt.

3
shawkinaw

Ich verwende das ionic Framework, das Hinzufügen des CSS-Stils funktioniert unter bestimmten Umständen möglicherweise nicht. Sie können versuchen, ng-if anstelle von ng-show/ng-hide zu verwenden

ref: https://books.google.com.my/books?id=-_5_CwAAQBAJ&pg=PA138&lpg=PA138&dq=ng-show+hide+flickering+in+ios&source=bl&ots=m2Turk8DFh&sig=8hNiWx26euGR2k=dex = y # v = onepage & q = ng-show% 20hide% 20flickering% 20in% 20ios & f = false

2
d1ck50n

Ich habe die oben beschriebene Lösung von ng-cloak ausprobiert, aber sie hat immer noch Probleme mit Firefox .. Die einzige Problemumgehung, die für mich funktionierte, bestand darin, das Laden des Formulars zu verzögern, bis Angular vollständig geladen ist.

Ich habe einfach ng-init in der App hinzugefügt und mit ng-if auf der Formularseite geprüft, ob die von mir gesetzte Variable bereits geladen ist.

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

sie sollten besser auf das Winkeldokument verweisen, da die Version [1.4.9] ein Update von unter enthält, das die Data-Ng-Cloak-Direktive unterstützen könnte. 

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

Es ist besser, ng-if anstelle von ng-show zu verwenden. ng-if entfernt das Element vollständig und erstellt es im DOM neu, wodurch das Blinken von Ng-Shows vermieden wird.

2
alexey

AS aus der obigen Diskussion 

[ng-cloak] {
                display: none;
            }

ist der perfekte Weg, um das Problem zu lösen. 

1
Dinesh Jain

Keine der oben aufgeführten Lösungen funktionierte für mich. Ich entschied mich dann für die eigentliche Funktion und stellte fest, dass beim Auslösen von "$ scope.watch" ein Wert in das Namensfeld gesetzt wurde, was nicht der Fall war. Also in den Code setze ich oldValue und dann newValue

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

Wenn in diesem Fall scope.watch ausgelöst wird, überwacht AngularJS die Änderungen an der Namensvariablen (model.value).

1
D.Adelakun

Wenn Sie feststellen, dass der Code des Vorlagencodes immer noch auftritt, befinden sich wahrscheinlich Ihre Skripts am unteren Rand der Seite. Dies bedeutet, dass die Direktive ng-cloak nicht funktioniert. Sie können Ihre Skripts entweder in den Kopf verschieben oder eine CSS-Regel erstellen.

Die Dokumente sagen: "Für das beste Ergebnis muss das Script angle.js im head-Abschnitt des HTML-Dokuments geladen werden; alternativ muss die obige css-Regel im externen Stylesheet der Anwendung enthalten sein."

Jetzt muss es kein externes Stylesheet sein, sondern nur ein Element im Kopf.

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

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

1
Elijah Lynn

Ich habe alle obigen Antworten ausprobiert und nichts hat funktioniert. Mit ionic eine Hybrid-App entwickeln und versuchte, eine Fehlermeldung nicht flimmern zu lassen. Am Ende habe ich mein Problem gelöst, indem ich meinem Element eine ng-hide-Klasse hinzugefügt habe. Mein div hat bereits ng-show, um das Element anzuzeigen, wenn ein Fehler auftritt. Durch das Hinzufügen von ng-hide wird festgelegt, dass div nicht angezeigt wird, bevor der Winkel geladen wird. Kein Ng-Cloak oder Neigungswinkel am Kopf notwendig.

1
gyleg5

Ich habe alle hier veröffentlichten Lösungen ausprobiert und flackerte immer noch in Firefox.

Wenn es jemandem hilft, habe ich es gelöst, indem ich style="display: none;" zum Hauptinhalt div hinzugefügt habe, dann mit jQuery (ich habe es bereits auf der Seite verwendet) $('#main-div-id').show();, sobald alles geladen wurde, nachdem Daten vom Server abgerufen wurden.

1
hipnosis

Ich verwende ng-show in einer Direktive, um Popups anzuzeigen und auszublenden.

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

Keines der oben genannten Dinge funktionierte für mich, und die Verwendung von ng-if anstelle von ng-show wäre ein Overkill. Das bedeutet, dass der gesamte Popup-Inhalt bei jedem Klick entfernt und in das DOM eingefügt werden muss. Stattdessen habe ich ein ng-if in dasselbe Element eingefügt, um sicherzustellen, dass es beim Laden des Dokuments nicht angezeigt wird:

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

Anschließend habe ich die Initialisierung mit einem Timeout in den für diese Anweisung zuständigen Controller eingefügt:

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

Auf diese Weise habe ich das Flackern-Problem beseitigt und den kostspieligen Vorgang des DOM-Einfügens bei jedem Klick vermieden. Dies ging mit der Verwendung von zwei Bereichsvariablen für denselben Zweck anstelle von einer einher. Dies ist jedoch auf jeden Fall die beste Option.

1
downhand

Ich fand den Vorschlag aus Rick Strahls Weblog mein Problem wurde perfekt behoben (da ich immer noch das seltsame Problem hatte, dass ng-cloak blinkend {{code}} gelegentlich blinkt, insbesondere während Firebug ausgeführt wurde):

Die Nuklearoption: Inhalte manuell ausblenden

Die Verwendung des expliziten CSS ist die beste Wahl, daher sollte Folgendes niemals erforderlich sein: Ich werde es hier jedoch erwähnen, da es einen Einblick gibt, wie Sie Inhalte beim Laden für andere Frameworks oder in Ihren eigenen markupbasierten Vorlagen manuell ausblenden/anzeigen können.

Bevor ich herausfand, dass ich den CSS-Stil explizit in die Seite einbetten konnte, hatte ich versucht herauszufinden, warum ng-cloak seine Aufgabe nicht erfüllt. Nachdem ich eine Stunde verschwendet hatte, um nirgendwohin zu gelangen, entschied ich mich schließlich, den Container manuell zu verstecken und zu zeigen. Die Idee ist einfach: Verbergen Sie zunächst den Container und zeigen Sie ihn dann an, nachdem Angular die Vorlage bearbeitet und das Vorlagen-Markup von der Seite entfernt hat.

Sie können den Inhalt manuell ausblenden und sichtbar machen, nachdem Angular die Kontrolle übernommen hat. Dafür habe ich verwendet:

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

Beachten Sie die Anzeige: Keine Formatvorlage, durch die das Element auf der Seite explizit ausgeblendet wird.

Sobald Angular die Initialisierung ausgeführt und die Vorlagenmarkierung auf der Seite effektiv verarbeitet hat, können Sie den Inhalt anzeigen. Für Angular ist dieses "ready" -Ereignis die app.run () - Funktion:

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

Dadurch wird die Anzeige effektiv entfernt: Kein Stil und der Inhalt wird angezeigt. Wenn app.run () ausgelöst wird, ist das DOM bereit, angefüllte Daten oder zumindest leere Daten anzuzeigen - Angular hat die Kontrolle übernommen.

1
Campbeln

Ich persönlich habe mich entschieden, das ng-class-Attribut anstelle des ng-show zu verwenden. Ich hatte viel mehr Erfolg auf dieser Route, insbesondere für Popup-Fenster, die standardmäßig nicht angezeigt werden. 

Was war früher <div class="options-modal" ng-show="showOptions"></div>

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

das CSS für die Optionsmodal-Klasse ist standardmäßig display: none. Die Showklasse enthält das display:block-CSS.

Ich würde den <ul> mit einem <div ng-cloak> umwickeln.

0
Dan Doyon

Versucht ng-cloak, blinkt aber immer noch kurz. Der folgende Code befreit sie vollständig.

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