forked from benpickles/js-model
/
js-model-0.8.1.min.js
17 lines (17 loc) · 4.92 KB
/
js-model-0.8.1.min.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* js-model JavaScript library, version 0.8.1
* (c) 2010 Ben Pickles
*
* Released under MIT license.
*/
var Model=function(a,b,c){b=b||{};c=c||{};var d=function(e){this.attributes=e||{};this.callbacks={};this.changes={};this.errors=new Model.Errors(this)};jQuery.extend(d,Model.Collection(b),{_name:a});jQuery.extend(d.prototype,Model.InstanceMethods,c);return d};Model.Collection=function(a){a=a||{};var b=function(c){this.collection=c||[];this.callbacks={}};jQuery.extend(b.prototype,Model.CollectionMethods,a,{chain:function(c){return new b(c)}});return new b};
Model.CollectionMethods={add:function(){for(var a=[],b=0;b<arguments.length;b++){var c=arguments[b];if(!this.detect(function(){return this.id()!==null&&this.id()==c.id()})){this.collection.push(c);a.push(c)}}a.length>0&&this.trigger("add",a);return this},all:function(){return this.collection},bind:function(a,b){this.callbacks[a]=this.callbacks[a]||[];this.callbacks[a].push(b);return this},count:function(){return this.collection.length},detect:function(a){var b;$.each(this.all(),function(c){if(a.call(this,
c)){b=this;return false}});return b},each:function(a){jQuery.each(this.all(),function(b){a.call(this,b)});return this},find:function(a){return this.detect(function(){return this.id()==a})},first:function(){return this.all()[0]||null},last:function(){var a=this.all();return a[a.length-1]||null},remove:function(a){var b=_.invoke(this.collection,"id");a=_.indexOf(b,a);if(a>-1){this.collection.splice(a,1);this.trigger("remove");return true}else return false},select:function(a){var b=[];$.each(this.all(),
function(c){a.call(this,c)&&b.push(this)});return this.chain(b)},sort:function(a){return this.chain(_.sortBy(this.all(),function(b,c){return a.call(b,c)}))},trigger:function(a,b){if(a=this.callbacks[a])for(var c=0;c<a.length;c++)a[c].apply(this,b||[]);return this}};Model.Errors=function(a){this.errors={};this.model=a};
Model.Errors.prototype={add:function(a,b){this.errors[a]||(this.errors[a]=[]);this.errors[a].push(b)},all:function(){return this.errors},clear:function(){this.errors={}},each:function(a){for(var b in this.errors)for(var c=0;c<this.errors[b].length;c++)a.call(this,b,this.errors[b][c])},on:function(a){return this.errors[a]||[]},size:function(){var a=0;this.each(function(){a++});return a}};
Model.InstanceMethods={attr:function(a,b){if(arguments.length===0)return jQuery.extend({},this.attributes,this.changes);else if(arguments.length===2){if(_.isEqual(this.attributes[a],b))delete this.changes[a];else this.changes[a]=b;return this}else if(typeof a==="object"){for(var c in a)this.attr(c,a[c]);return this}else return a in this.changes?this.changes[a]:this.attributes[a]},bind:function(a,b){this.callbacks[a]=this.callbacks[a]||[];this.callbacks[a].push(b);return this},callPersistMethod:function(a,
b){var c=this,d=function(){if(a==="create")c.constructor.add(c);else a==="destroy"&&c.constructor.remove(c.id())},e=function(f){if(f){c.merge(c.changes).reset();d();c.trigger(a)}var g;if(b)g=b.apply(c,arguments);return g};this.constructor.persistence?this.constructor.persistence[a](this,e):e.call(this,true)},destroy:function(a){this.callPersistMethod("destroy",a);return this},id:function(){return this.attributes.id||null},merge:function(a){jQuery.extend(this.attributes,a);return this},newRecord:function(){return this.id()===
null},reset:function(){this.errors.clear();this.changes={};return this},save:function(a){if(this.valid())this.callPersistMethod(this.newRecord()?"create":"update",a);else a&&a(false);return this},trigger:function(a,b){if(a=this.callbacks[a])for(var c=0;c<a.length;c++)a[c].apply(this,b||[]);return this},update:function(a){this.merge(a).trigger("update");return this},valid:function(){this.errors.clear();this.validate();return this.errors.size()===0},validate:function(){return this}};
Model.Log=function(){window.console&&window.console.log.apply(window.console,arguments)};
Model.RestPersistence=function(a,b){var c=function(){this.resource=a};jQuery.extend(c.prototype,{create:function(d,e){return this.xhr("POST",this.create_path(d),d,e)},create_path:function(){return this.resource},destroy:function(d,e){return this.xhr("DELETE",this.destroy_path(d),d,e)},destroy_path:function(d){return this.update_path(d)},params:function(d){var e;if(d){var f=d.attr();delete f.id;e={};e[d.constructor._name.toLowerCase()]=f}else e=null;return e},parseResponseData:function(d){try{return jQuery.parseJSON(d.responseText)}catch(e){Model.Log(e)}},
update:function(d,e){return this.xhr("PUT",this.update_path(d),d,e)},update_path:function(d){return[this.resource,d.id()].join("/")},xhr:function(d,e,f,g){var h=this,i=d==="DELETE"?null:this.params(f);return jQuery.ajax({type:d,url:e,dataType:"text",data:i,complete:function(j,k){h.xhrComplete(j,k,f,g)}})},xhrComplete:function(d,e,f,g){var h=this.parseResponseData(d);e=e==="success";if(h)if(e)f.attr(h);else if(d.status===422){f.errors.clear();for(var i in h)for(var j=0;j<h[i].length;j++)f.errors.add(i,
h[i][j])}g&&g.call(f,e,d)}},b);return new c};