Skip to content

Instantly share code, notes, and snippets.

@EyePulp
Last active December 18, 2015 04:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save EyePulp/5725157 to your computer and use it in GitHub Desktop.
Save EyePulp/5725157 to your computer and use it in GitHub Desktop.
knockout.js, jquery, and tastypie: Automattically perform a "PUT" to your model's resource_uri when certain observables change value
// usage inside a vm:
var fooVM = function(){
var self = this;
var resource_uri = ko.observable('/api/v1/foo/');
var bar = ko.observable(1);
var baz = ko.observable(1);
ko.saveOnChange(self,['bar']);
}
var f = new fooVM();
f.bar(2); // causes a PUT to /api/v1/foo/
f.baz(2); // doesn't do anything
// provided an instance of a vm and an array of observable names within it
// will subscribe to changes, and kick off an ajax PUT to the vm.resource_uri value
// tries to autodetect use of ko.mapping vs standard ko for the toJS conversion
ko.saveOnChange = function(vm,observables,uri,method,pre_save_fn,post_save_fn){
vm._saving = ko.observable(false);
vm._last_saved = ko.observable(null);
vm._save_on_change_uri = uri;
vm._save_on_change_method = method || 'PUT';
vm._pre_save_fn = pre_save_fn;
vm._post_save_fn = post_save_fn;
// delay activating this because
setTimeout(_.bind(function(vm,observables){
var self = this;
self.vm = vm;
self.vm._save_on_change_uri = self.vm._save_on_change_uri || self.vm.resource_uri();
// console.log('attaching to',self.vm.id(),observables);
ko.utils.arrayForEach(observables, function(o) {
var ob = self.vm[o];
if (ko.isObservable(ob)){
// TODO: how do we remove this bind function to avoid lodash/underscore?
ob.subscribe(_.bind(function(vm,val){
if (vm._pre_save_fn){
vm._pre_save_fn(vm);
}
vm._saving(true);
var toJS = (vm.__ko_mapping__ && ko.mapping)?ko.mapping.toJS:ko.toJS();
vm._saving(true);
$.ajax({
type : vm._save_on_change_method
, url : vm._save_on_change_uri
, data : JSON.stringify(toJS(vm))
, processData : false
, dataType : "json"
, contentType : "application/json"
, success : function(data){
vm._saving(false);
vm._last_saved((new Date()));
if (vm._post_save_fn){
vm._post_save_fn(vm,data);
}
// console.log('save response :',data);
}
});
},this,self.vm));
}else{
console.error('ERROR: ko.saveOnChange() -- "' + ob + '" is not a ko.observable');
}
});
},this,vm,observables),5);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment