Was ist der beste Weg, um den Bildschirm auszublenden, während Knockout-JS-Bindungen erstellt werden?

76

Ich bin ein großer Knockoutjs-Fan. Ich benutze es jetzt für meine gesamte Webentwicklung und liebe es einfach. Eine Sache, die ich jedoch nicht herausfinden konnte, ist, wie die Benutzeroberfläche ausgeblendet wird, während die Knockout-Bindungen erstellt werden.

Zum Beispiel habe ich eine sehr robuste Benutzeroberfläche mit vielen Vorlagen, die auf meiner Seite verwendet werden. Das Problem, das mir auffällt, ist, dass der Benutzer beim ersten Besuch der Seite alle meine Vorlagen für den Bruchteil einer Sekunde sieht, bevor die Bindungen aktiviert werden.

Was ist der beste Weg, um dieses Problem zu beheben? Ich habe versucht, Hilfsklassen zu verwenden, um sie auszublenden, aber dann können die Vorlagen nicht mit den Bindungen 'sichtbar' und 'wenn' angezeigt werden, es sei denn, ich entferne die Referenz der Hilfsklasse (dh ui-helper-hidden).

Luc
quelle

Antworten:

71

Es gibt einige Strategien, die Sie hier anwenden können.

-Eine besteht darin, Ihren gesamten Inhalt in Vorlagen zu platzieren, die in Skript-Tags gespeichert sind (funktioniert gut mit nativen Vorlagen). Innerhalb der Vorlage können Sie dann Kontrollflussbindungen verwenden. Das wäre wie folgt:

<div data-bind="template: 'contentTmpl'"></div>

<script id="contentTmpl" type="text/html">
   <ul data-bind="foreach: items">
       <li data-bind="text: name"></li>
   </ul>
</script>

- Eine andere Möglichkeit besteht darin, style="display: none"das Containerelement zusammen mit einer visibleBindung zu verwenden, die an ein loadedObservable gebunden werden kann, wobei Sie das Observable truenach dem Anwenden der Bindungen ändern .

RP Niemeyer
quelle
1
Für die Aufzeichnung habe ich den "geladenen" Vorschlag verwendet, und er hat bei mir nicht funktioniert. Alle meine js-Referenzen befinden sich am Ende meiner Seite, und das Markup war bis zum Aufruf von applyBindings (allerletzte Zeile von js) sichtbar. Ich wollte dies nur als Notiz hinzufügen, da dies das Problem war, das ich ursprünglich zu lösen versuchte. Danke noch einmal!
Luc
4
Ich habe die Antwort bearbeitet, um zu beschreiben, wie das loadedObservable funktionieren könnte. Sie müssen style="display: none"ein Containerelement zusammen mit hinzufügen visible: loadedund es dann auf true umschalten, nachdem Ihre Bindungen angewendet wurden. Die visibleBindung entfernt das display: none(es kann nicht steuern, was in Ihrem CSS ist).
RP Niemeyer
@RPNiemeyer, der zweite Ansatz ist für SEO möglicherweise nicht so gut geeignet, wenn der Server Nicht-JS-Seiten zurückgibt. In meinem Fall fügt Knockout der vom Server generierten Benutzeroberfläche eine Ebene hinzu, die display:nonemöglicherweise nicht von Bots erfasst wird.
Jason J. Nathan
196

Ich habe nur danach gegoogelt und nachdem ich den beobachtbaren Weg gewählt hatte, dachte ich an einen anderen Ansatz:

<div style="display: none" data-bind="visible: true">
  <ul data-bind="foreach: items">
    <li data-bind="text: name"></li>
  </ul>
</div>

Sie benötigen keine Observable, die sichtbare wird immer als true ausgewertet, sobald die Datenbindung abgeschlossen ist.

Jason More
quelle
13
Ausgezeichnet! Eine weitere Optimierung zusätzlich, wenn Sie diese zusätzliche Div nicht wollen: <ul data-bind="foreach: items, visible: true"> <li data-bind="text: name"></li> </ul>
Greg R
15
Danke dafür! Ich sollte hinzufügen, dass ich gerade den Stil / die Datenbindung zu meinem vorhandenen div hinzugefügt habe und aus irgendeinem Grund nur einen Teil davon versteckt habe. Also habe ich eine äußere Div hinzugefügt. Übrigens habe ich das auch schon <div data-bind='visible: false'> Screen loading... </div>
mal
3
Ausgezeichnet! Sie könnten auch ein div haben, das eine Ladeanimation mit dem Daten-Bing "sichtbar: falsch" enthält.
Michael Fry
1
Angular versucht viel zu viel zu tun. Ich werde immer die Einfachheit des Knockouts in Kombination mit anderen Bibliotheken wie SammyJS bevorzugen
pim
1
Ein bisschen zu spät zur Party vielleicht, aber Sie könnten tun, <div class="beforeReady" data-bind="css: {ready: true}">wenn Sie CSS-Animationen machen wollten, um es anzuzeigen (wie Deckkraft oder etwas)
Thomas
0

Hier ist eine Nur-CSS-Methode, wenn Sie befürchten, dass nicht gestaltete Widgets vor der Bindung für MVVM-Implementierungen angezeigt werden .

[data-role]:not([role], [tabindex]) {
    visibility: hidden;
}

Ich habe es nicht auf allen Kendo-Widgets getestet, aber es scheint für die meisten zu funktionieren.

Sonniger Patel
quelle
0

Hier ist ein alternativer Ansatz, bei dem Klassen für "Verstecken und" Anzeigen "anstelle eines Inline-Stils verwendet werden. Fügen Sie dem Element, das bis zum Laden des Inhalts ausgeblendet werden soll, eine" Verstecken "-Klasse hinzu und fügen Sie eine" CSS "-Datenbindung hinzu, um sie zu erstellen angezeigt werden, wenn es gebunden ist.

<div class="hide" data-bind="css: {'show': true}">

</div>

Die Klassen 'hide' und 'show' sind bereits in Bootstrap definiert.

Wenn Bootstrap nicht verwendet wird, kann das CSS wie folgt definiert werden:

.hide {
  display: none !important;
}
.show {
  display: block !important;
} 

Die Reihenfolge ist wichtig. Die Klasse "hide" sollte vor "show" definiert werden.

MEIN K
quelle