2

So I have a page in my application that uses a fairly standard nested model implementation, along the lines of the standard Customer -> Order -> OrderLineItems type. The difference for me is that the model at OrderLineItems is pretty complex.

In my code, both with observable arrays as well as observables, in order to update my view correctly, I find that I wind up calling "myObservable.valueHasMutated()" quite a lot.

It's a gut feel that having to do this manually isn't quite as it should be--but I'm not sure where to look to know what might need changing. So a few questions:

  1. Is this just normal for "deep/big" models?
  2. Is there something obvious I might look for to address this?
  3. Is there an example on the web of complex models like this implemented with KO?

An example of what I have in my viewmodel:

self.projectsVisible = ko.observable(false);
self.toggleProjectVisibility = function () {
    self.projectsVisible(!self.projectsVisible());
    self.projectsVisible.valueHasMutated();
};

That's tied to a button element, and a DIV:

<div data-bind="visible: projectsVisible">
    <table>
        <thead data-bind="template: {name: 'projectHeader'}"></thead>
        <tbody data-bind="template: {name: 'project', foreach: projects}"></tbody>
    </table>
</div>
<button type="button" data-bind="click: toggleProjectVisibility">
  Toggle Projects On/Off
</button>
reallyJim
  • 1,336
  • 2
  • 16
  • 32
  • 5
    Maybe you can get something in jsFiddle that shows the issue? There are very few cases where you should need to call `valueHasMutated` yourself. Generally this would be used when you modify an object/array directly that an observable/observableArray holds and want to trigger an update or when you created a subscription and want to trigger it immediately. You situation where you are toggling a boolean should not require it. I think that a jsFiddle would help us narrow it down. – RP Niemeyer Nov 10 '12 at 02:07
  • I had a similar problem. JSFiddle here: http://jsfiddle.net/b22Ex/2/ In this question, http://stackoverflow.com/questions/15798881/kogrid-update-cell it was suggested that I call valueHasMutated() in order for my change to take effect. – krasnaya Apr 04 '13 at 14:18

1 Answers1

0

I use valueHasMutated mainly for observableArray changes.

In your example, self.projectsVisible(!self.projectsVisible()); already notifies the subscribers since the value always changes. Thus, calling valueHasMutated notifies the subscribers a second time for the same value change.

You can check this fiddle: http://jsfiddle.net/5RU7n/

In the case you want to notify the subscribers of a write operation on an observable even when the value remains the same, you can use the .extend({ notify: 'always' }) extender (see http://knockoutjs.com/documentation/observables.html).

Finally, I think you can try to enumerate the situations in which you call valueHasMutated, you may end up finding by yourself redundant calls.

GôTô
  • 7,974
  • 3
  • 32
  • 43