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.

Jeroen
  • 60,696
  • 40
  • 206
  • 339
THX-1138
  • 21,316
  • 26
  • 96
  • 160

4 Answers4

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.

RP Niemeyer
  • 114,592
  • 18
  • 291
  • 211
  • 5
    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). – Patrick M Aug 07 '12 at 16:18
  • It sure would be nice if for nothing else - testing in chrome. – Scott Romack Jan 20 '13 at 00:50
  • Your viewModel can, itself, be an observable, so you could call `myViewModel.valueHasMutated()` to update the whole view. – Roy J Aug 09 '16 at 12:53
  • 2
    Doesn't work on arrays here either. In fact arrays don't seem to work at all in Knockout. I miss Angular :-( – garryp Sep 16 '16 at 15:48
  • 2
    It does work on KnockoutObservableArrays as of KO 3.5 – balint Aug 02 '19 at 12:34
  • There is a "dirty refresh" method for when `valueHasMutated` doesn't work on an observableArray, see here: https://stackoverflow.com/a/13231783/3437953 – mft25 Mar 26 '20 at 17:28
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))
ebram khalil
  • 8,252
  • 7
  • 42
  • 60
ProfNimrod
  • 4,142
  • 2
  • 35
  • 54
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 -->
0

An easy alternative is to clear the observable array:

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

Note: This alternative could perhaps suffer in performance.

Simon
  • 4,157
  • 2
  • 46
  • 87