Reputation: 429
I'm starting to use Knockout Mapping, I'm missing something obvious?
When the AJAX call is made the binding fails as the data hasn't yet been returned. One way around that is to set up an empty JSON response to prepolulate the viewmodel, but to me that doesn't seem right. It would be good if the requirement for an initial empty JSON object could be dropped.
Is there way around this? writing this I'm beginning to think delaying the binding until after the first JSON query has returned.
thanks
Upvotes: 1
Views: 688
Reputation: 429
The problem came up again, and searched anew.
I found this rather good knockout tips page if you scroll down to "Undefined Properties" it suggests prefixing the parameter with "$data."
To quote "In JavaScript it is an error to attempt to retrieve the value of a variable that is not defined, but it is fine to access an undefined property off of another object"
Thanks for the help, but this is an almost invisible light weight fix.
Upvotes: 0
Reputation: 18749
Here is a cut down example...
$(function () {
$(function () {
function userposition(position, sduid, userName) {
this.position = ko.observable(position);
this.userId = ko.observable(sduid);
this.userName = ko.observable(userName);
}
function overallTablesViewModel() {
this.userpositions = ko.observableArray([]);
var userpositions = this.userpositions;
var options = {};
this.FilterClick = function () {
options =
{
Prop1: value,
Prop2: value
};
if (sportId < 1) {
toastr.error('You need to select a sport.');
return;
}
$.getJSON('url', options, function (json) {
var mappedData = ko.utils.arrayMap(json, function (up) {
return new userposition(up.Position, up.SDUID, up.UserName);
});
userpositions(mappedData);
});
};
}
//set up the viewmodel
var viewModel = new overallTablesViewModel();
ko.applyBindings(viewModel, $("#overallTablevm")[0]);
});
});
My example is using a click event, but you can take that out. You can see that the ViewModel
calls a url
, and the json
returned builds an observableArray
of userposition
.
The view will then have a property userpositions
that holds the data.
Upvotes: 1
Reputation: 70122
I would use a Knockout template, as detailed in the template binding documentation. The basic approach is that you take your current HTML that binds to the results of the AJAX call, and move this into a template.
You then have a property on your top-level view model which is the JSON results that you obtain via the AJAX call:
<div data-bind="template: { name: 'my-template', data: myAjaxResponse}"></div>
Upvotes: 0