Reputation: 83356
One intuitive way I though I'd be able to use KO mappings plugin would be to create a naked viewModel with only whatever computed observables I needed, then update the vm with fromJS
whenever server results came in. I assumed missing properties would be added, and existing ones would be updated.
I thought I could just bind this naked ViewModel to my dom on document.ready, with any missing properties showing up blank. Then, when an ajax callback fires, and the mapping library adds the new properties, the dom would update.
The results I saw seem to indicate that this isn't possible though, and I wanted to make sure I'm not missing anything.
The code is below, but the three main problems I found were:
If the dom is bound to a property that's missing from the ViewMoel, that's an error. This isn't surprising, especially given the lucid explanation below from @madcapnmckay.
If a computed observable references a view model property that's absent from the ViewModel, that's an error. I assume this is the case since all computedObservables are executed immediately so that KO can track which observable properties the computedObservable is dependent upon.
Most devastating, it looks like an existing ViewModel can only be updated with fromJS
if that ViewModel was originally created with fromJS
. Peeking in the code it looks like fromJS
looks in the second parameter—if one is passed—to check for a mappings property.
I don't need any help working around this. I've already come up with a simple way to deal with all this; I just want to make sure there's not something simple I'm missing on any of the above three bullets that would make things more easy.
VM:
var vm = new (function () {
this.prettyName = ko.computed(function () {
return this.title() + " " + this.name();
}, this);
})();
"AJAX" result:
var serverObj = {
title: 'Mr.',
name: 'Adam Rackis',
degreeValue: 2,
degreeTypes: [{ val: 1, txt: 'Bachelors' }, { val: 2, txt: 'Masters' }, { val: 3, txt: 'PhD'}]
};
HTML
<div id="educationPane">
Name: <input type="text" data-bind="value: prettyName" />
Degree: <select data-bind="{foreach: degreeTypes, value: degreeValue}">
<option data-bind="{text: text, value: val}"></option>
</select>
</div>
Upvotes: 1
Views: 131
Reputation: 15984
I have hit all of these same issues when working with KO. Point 1 and 2 in my opinion is simply a consequence of how KO works.
Point 3 I concede is a pain. I don't know the reasons it was done this way. Maybe there were some good reasons. At the very least an 'update' method that simply updates properties and doesn't remove from collections would be useful.
Hope this helps.
Upvotes: 1