Reputation: 15
I am having issues with what seemed like an easy idea.
I am trying to create ko.observable()
's dynamically from server provided data.
The server is sending me a ~240 value JSON array. I want to create an observable for each one as I am putting them into an online form.
function AppViewModel() {
var self = this;
var data = {};
$.getJSON("/record/20001", function(data) {
$.each(data, function(i, val) {
self.data[i] = ko.observable(val);
});
});
self.test = 5;
self.test2 = ko.observable(69);
}
vm = new AppViewModel();
ko.applyBindings(vm);
With this I was unable to access any of the data.
function AppViewModel() {
var self = this;
self.abnorm_comment = ko.observable();
self.abnorm_test1 = ko.observable();
self.abo_sys_spec = ko.observable();
self.access_location = ko.observable();
self.ace_inhibit = ko.observable();
/*
A myriad of line like these, written by hand
*/
self.xray_other = ko.observable();
$.getJSON("/record/20001", function (data) {
$.each(data, function (i, val) {
self[i](val);
});
});
self.test = 5;
self.test2 = ko.observable(69);
}
function AppViewModel() {
var self = this;
var data = {};
$.getJSON("/record/20001", function (data) {
$.each(data, function (i, val) {
self.data[i] = ko.observable(val);
});
});
}
And access it like so:
<input type="text" data-bind="value: data.case_id">
For the first try my view model has no data in it. If I pull up the vm
variable in the Chrome console it does have the data though.
Am I doing something wrong here? The second way that works does not look very nice with so many observables.
Please let me know if I am missing something obvious
It ended up that I was having a race condition between applying the bindings and the the AJAX server request. I also ended up using the plugin as recommended by @JotaBe
Upvotes: 0
Views: 1404
Reputation: 39025
You can use the ko.mapping plugin which will do it for you.
The advantages are that this plugin is well tested, and is able to map more complex data, like arrays, or nested properties.
You can map from JSON, or from an already instanced JavaScript object. The synatx is as simple as this:
var viewModel = ko.mapping.fromJSON(data);
Another advantage is that it can also update your local mapped copy from new updated data coming from the server, without rebuilding the whole object. This also helps in updating the view, without the need to rebuild (or unbind) it.
And a final advantage is taht it also allows to get back the JSON or JavaScript object if you need to post it back to the server, simply like this:
var unmapped = ko.mapping.toJS(viewModel);
Upvotes: 1
Reputation: 9340
This has worked reliably for me in the past:
jsonToObservable = function (obj, data) {
for (var p in data) {
var temp = data[p];
obj[p] = ko.observable(temp);
}
};
Upvotes: 2