How to force a view refresh without having it trigger automatically from an observable?
Asked Answered
A

4

156

Note: this is mostly for debugging and understanding KnockoutJS.

Is there a way to explicitly request Knockout to refresh the view from (already bound) view model? I am looking for something like:

ko.refreshView();

I understand that this is not an intended use of Knockout, but I still want to know if there is a such method for debugging and learning purposes.

Anethole answered 16/12, 2011 at 16:49 Comment(0)
S
260

You can't call something on the entire viewModel, but on an individual observable you can call myObservable.valueHasMutated() to notify subscribers that they should re-evaluate. This is generally not necessary in KO, as you mentioned.

Soffit answered 16/12, 2011 at 17:17 Comment(6)
You can also iterate over the data context, searching for elements that have a valueHasMutated property which is of type function and calling it for each of them. That should get all of your observables, but it's bad practice and conceivably fire off a whole lot more updates than you anticipate (think computed dependency chains).Mountford
It sure would be nice if for nothing else - testing in chrome.Pilothouse
Your viewModel can, itself, be an observable, so you could call myViewModel.valueHasMutated() to update the whole view.Streamway
Doesn't work on arrays here either. In fact arrays don't seem to work at all in Knockout. I miss Angular :-(Hanseatic
It does work on KnockoutObservableArrays as of KO 3.5Wileywilfong
There is a "dirty refresh" method for when valueHasMutated doesn't work on an observableArray, see here: https://mcmap.net/q/152848/-refresh-observablearray-when-items-are-not-observablesCantabrigian
C
25

In some circumstances it might be useful to simply remove the bindings and then re-apply:

ko.cleanNode(document.getElementById(element_id))
ko.applyBindings(viewModel, document.getElementById(element_id))
Convalescent answered 19/5, 2013 at 14:5 Comment(4)
Thanks for the edit ebram... Guess I should've mentioned I use coffeescript ;-)Convalescent
Watch out if you also use jQuery (e.g. when migrating bits of the app to ko) as cleanNode will also remove other dom events.Zacynthus
This is perfect. I can't get KO to recognize NEW dom children with data-bind attributes after a viewmodel has been applied.Hermosa
Perfect! Working!Brummett
E
0

I have created a JSFiddle with my bindHTML knockout binding handler here: https://jsfiddle.net/glaivier/9859uq8t/

First, save the binding handler into its own (or a common) file and include after Knockout.

If you use this switch your bindings to this:

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

OR

<!-- ko bindHTML: htmlValue --><!-- /ko -->
Eurythermal answered 4/9, 2016 at 21:2 Comment(0)
L
0

An easy alternative is to clear the observable array:

let tmp = myObservableArray();
myObservableArray([]);
myObservableArray(tmp);

Note: This alternative could perhaps suffer in performance.

Loella answered 12/10, 2022 at 8:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.