Skip to content

Instantly share code, notes, and snippets.

@inadarei
Created May 9, 2012 06:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save inadarei/2642523 to your computer and use it in GitHub Desktop.
Save inadarei/2642523 to your computer and use it in GitHub Desktop.
var UserModel = function () {
var self = this;
// Somewhat sophisticated loading flag that supports parallel loading of multiple endpoints.
self.loading = ko.observableArray();
// Encapsulating the entire form in a property, so we can use ko.mapping in a safe way.
// If properties were directly on the model, we'd have to re-init model every time we
// load data, which could lead to unwanted consequences.
self.user = ko.observable();
self.availableCountries = ko.observableArray([]);
self.availableLanguages = ko.observableArray([]);
// Save data
self.save = function(form) {
// ...
};
// Loads user.
self.load = function() {
// Important: we need to load countries and languages first and only then load the user, to make
// sure that corresponding drop-downs are populated before loaded user will try to set values on them
// loadUser() is run once, after both loadCountries() and loadLanguages() have run (they do run in parallel!)
var parallelExecutions = [self.loadCountries, self.loadLanguages];
var delayedLoadUser = _.after(parallelExecutions.length, self.loadUser);
_.each(parallelExecutions, function(func) {
func({success: delayedLoadUser});
});
};
// Load all available countries /v1/countries
self.loadCountries = function(ctx) {
// Let loading indicator know that there's a new loading task that ought to complete
self.loading.push(true);
$.getJSON('/v1/countries',
function(data) {
console.log("loaded countries")
console.dir(data);
self.availableCountries(data);
// Let loading indicator know that this task has been completed
self.loading.pop();
// Try to call success callback, which is loadUser if and only if all parallel processes have completed
if (ctx && ctx.success !== 'undefined') {ctx.success();}
}
);
}
// Load all available languages /v1/languages
self.loadLanguages = function(ctx) {
self.loading.push(true);
$.getJSON('/v1/languages',
function(data) {
console.log("loaded languages")
console.dir(data);
self.availableLanguages(data);
self.loading.pop();
if (ctx && ctx.success !== 'undefined') {ctx.success();}
}
);
}
self.loadUser = function() {
self.loading.push(true);
// Load the main user object
$.getJSON('/v1/users/' + userId,
function(data) {
console.dir(data);
var loadedUser = {};
// Extremely important: map data while keeping everything observable!
ko.mapping.fromJS(data, {}, loadedUser);
self.user(loadedUser);
self.loading.pop();
}
);
}
}
//Activates knockout.js
$(document).ready(function () {
var userModel = new UserModel();
ko.applyBindings(userModel);
// Load initial data via Ajax
userModel.load();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment