Wie erzwinge ich eine Ansichtsaktualisierung, ohne dass sie automatisch von einem Observable ausgelöst wird?

151

Hinweis: Dies dient hauptsächlich zum Debuggen und Verstehen von KnockoutJS.

Gibt es eine Möglichkeit, Knockout explizit aufzufordern, die Ansicht aus dem (bereits gebundenen) Ansichtsmodell zu aktualisieren? Ich suche so etwas wie:

ko.refreshView();

Ich verstehe, dass dies keine beabsichtigte Verwendung von Knockout ist, aber ich möchte trotzdem wissen, ob es eine solche Methode zum Debuggen und Lernen gibt.

THX-1138
quelle

Antworten:

252

Sie können nicht im gesamten viewModel etwas aufrufen, aber in einem einzelnen Observable können Sie anrufen myObservable.valueHasMutated(), um Abonnenten zu benachrichtigen, dass sie eine Neubewertung durchführen sollten. Dies ist in KO im Allgemeinen nicht erforderlich, wie Sie erwähnt haben.

RP Niemeyer
quelle
5
Sie können auch den Datenkontext durchlaufen, nach Elementen mit einer valueHasMutatedEigenschaft vom Typ suchen functionund diese für jedes Element aufrufen. Das sollte alle Ihre Observablen erhalten, aber es ist eine schlechte Praxis und es ist denkbar, dass Sie viel mehr Updates abfeuern, als Sie erwarten (denken Sie an berechnete Abhängigkeitsketten).
Patrick M
Es wäre sicher schön, wenn für nichts anderes - Testen in Chrom.
Scott Romack
Ihr viewModel kann selbst beobachtbar sein, sodass Sie aufrufen können myViewModel.valueHasMutated(), um die gesamte Ansicht zu aktualisieren.
Roy J
2
Funktioniert auch hier nicht mit Arrays. Tatsächlich scheinen Arrays in Knockout überhaupt nicht zu funktionieren. Ich vermisse Angular :-(
Garryp
2
Es funktioniert auf KnockoutObservableArrays ab KO 3.5
balint
25

Unter bestimmten Umständen kann es nützlich sein, die Bindungen einfach zu entfernen und dann erneut anzuwenden:

ko.cleanNode(document.getElementById(element_id))
ko.applyBindings(viewModel, document.getElementById(element_id))
ProfNimrod
quelle
Danke für die Bearbeitung ebram ... Ich denke, ich hätte erwähnen sollen, dass ich Coffeescript benutze ;-)
ProfNimrod
15
Achten Sie darauf, ob Sie auch jQuery verwenden (z. B. beim Migrieren von Teilen der App nach ko), da cleanNode auch andere dom-Ereignisse entfernt.
Dan Revell
Dies ist perfekt. Ich kann KO nicht dazu bringen, NEUE dom-Kinder mit Datenbindungsattributen zu erkennen, nachdem ein Ansichtsmodell angewendet wurde.
Andrew T Finnell
Perfekt! Arbeiten!
jeff_drumgod
0

Ich habe hier mit meinem bindHTML-Knockout-Bindungshandler eine JSFiddle erstellt: https://jsfiddle.net/glaivier/9859uq8t/

Speichern Sie zunächst den Bindungshandler in einer eigenen (oder einer allgemeinen) Datei und fügen Sie ihn nach dem Knockout ein.

Wenn Sie diesen Schalter verwenden, gehen Sie wie folgt vor:

<div data-bind="bindHTML: htmlValue"></div>

OR

<!-- ko bindHTML: htmlValue --><!-- /ko -->
James 'Fluffy' Burton
quelle