I'm struggling with how to update my bound viewmodel from an ajax call whilst using a validatedObservable
.
Previously I get the initial data from an ajax call and intially bound like this:
self.quote = ko.mapping.fromJS(result.data, self.quoteMapping);
ko.applyBindings(self);
and when a user changed something in the 'quote', I'd make another ajax call passing the changes and the return from the ajax call would be the complete 'quote' (and I do need to bring the whole 'quote', as a change to one item on the quote can server-side affect other items and also other properties in the top level which therefore need to be updated in the client-side view model) which I would update the bound view model with (using the other signature of fromJS), thusly:
ko.mapping.fromJS(result.data, self.quote);
However, now I want the view model to be a validatedObservable
. For the inital load this is pretty straightforward:
self.quote = ko.validatedObservable(ko.mapping.fromJS(result.data, self.quoteMapping));
ko.applyBindings(self);
but I'm stuck on how to update the view model with a validated observable
I can't use ko.mapping.fromJS(result.data, self.quote); because that will update self.quote with a plain observable not a validated observable and unsurpisingly that doesn't work.
Here are a couple of very simplified fiddles to illustrate the problem.
Plain Observable (which works): https://jsfiddle.net/stevedavey/1tup0agt/
Validated Observable (which doesn't): https://jsfiddle.net/stevedavey/yh233wht/
I'd appreciate any clue as to what I need to do to be able to get an amended 'quote' from an ajax call and update my validated observable using ko mapping.
I suspect I'm misunderstanding something fundamental.
I can't use
ko.mapping.fromJS(result.data, self.quote);
because that will update self.quote with a plain observable not a validated observable and unsurpisingly that doesn't work.
You can use ko.mapping.fromJS
, you're just doing it wrong. Take the time to read the documentation of the mapping plugin - it's only one page and not even a long one.
You can define additional behavior by passing an options object. In this case you want to customize object creation using create
- like returning a validated observable.
I'm citing the documentation example with one change:
var mapping = {
'children': {
create: function(options) {
return ko.validatedObservable(options.data);
}
}
}
var viewModel = ko.mapping.fromJS(data, mapping);
Of course you can use create
at the root level of the mapping options, too, but the mapping plugin also allows you to be more specific.
Side note: Try to re-use the same function to initialize and to update your viewmodel. There is no real reason to keep two different pieces of code around that update the same observable.