Merging master

This commit is contained in:
Jeremy Ashkenas
2010-10-25 12:44:41 -04:00
9 changed files with 346 additions and 378 deletions

27
backbone-min.js vendored
View File

@@ -1,15 +1,16 @@
(function(){var f;f=typeof exports!=="undefined"?exports:this.Backbone={};f.VERSION="0.1.2";var e=this._;if(!e&&typeof require!=="undefined")e=require("underscore")._;var h=this.jQuery;f.emulateHttp=false;f.Events={bind:function(a,b){this._callbacks||(this._callbacks={});(this._callbacks[a]||(this._callbacks[a]=[])).push(b);return this},unbind:function(a,b){var c;if(a){if(c=this._callbacks)if(b){c=c[a];if(!c)return this;for(var d=0,g=c.length;d<g;d++)if(b===c[d]){c.splice(d,1);break}}else c[a]=[]}else this._callbacks=
(function(){var f;f=typeof exports!=="undefined"?exports:this.Backbone={};f.VERSION="0.2.0";var e=this._;if(!e&&typeof require!=="undefined")e=require("underscore")._;var h=this.jQuery;f.emulateHttp=false;f.Events={bind:function(a,b){this._callbacks||(this._callbacks={});(this._callbacks[a]||(this._callbacks[a]=[])).push(b);return this},unbind:function(a,b){var c;if(a){if(c=this._callbacks)if(b){c=c[a];if(!c)return this;for(var d=0,g=c.length;d<g;d++)if(b===c[d]){c.splice(d,1);break}}else c[a]=[]}else this._callbacks=
{};return this},trigger:function(a){var b,c,d,g;if(!(c=this._callbacks))return this;if(b=c[a]){d=0;for(g=b.length;d<g;d++)b[d].apply(this,Array.prototype.slice.call(arguments,1))}if(b=c.all){d=0;for(g=b.length;d<g;d++)b[d].apply(this,arguments)}return this}};f.Model=function(a){this.attributes={};this.cid=e.uniqueId("c");this.set(a||{},{silent:true});this._previousAttributes=e.clone(this.attributes);this.initialize&&this.initialize(a)};e.extend(f.Model.prototype,f.Events,{_previousAttributes:null,
_changed:false,toJSON:function(){return e.clone(this.attributes)},get:function(a){return this.attributes[a]},set:function(a,b){b||(b={});if(!a)return this;if(a.attributes)a=a.attributes;var c=this.attributes;if(this.validate){var d=this.validate(a);if(d){b.error?b.error(this,d):this.trigger("error",this,d);return false}}if("id"in a)this.id=a.id;for(var g in a){d=a[g];if(d==="")d=null;if(!e.isEqual(c[g],d)){c[g]=d;if(!b.silent){this._changed=true;this.trigger("change:"+g,this,d)}}}!b.silent&&this._changed&&
this.change();return this},unset:function(a,b){b||(b={});var c=this.attributes[a];delete this.attributes[a];if(!b.silent){this._changed=true;this.trigger("change:"+a,this);this.change()}return c},fetch:function(a){a||(a={});var b=this,c=a.error&&e.bind(a.error,null,b);f.sync("read",this,function(d){if(!b.set(d.model,a))return false;a.success&&a.success(b,d)},c);return this},save:function(a,b){a||(a={});b||(b={});if(!this.set(a,b))return false;var c=this,d=b.error&&e.bind(b.error,null,c),g=this.isNew()?
"create":"update";f.sync(g,this,function(i){if(!c.set(i.model,b))return false;b.success&&b.success(c,i)},d);return this},destroy:function(a){a||(a={});var b=this,c=a.error&&e.bind(a.error,null,b);f.sync("delete",this,function(d){b.collection&&b.collection.remove(b);a.success&&a.success(b,d)},c);return this},url:function(){var a=j(this.collection);if(this.isNew())return a;return a+"/"+this.id},clone:function(){return new this.constructor(this)},isNew:function(){return!this.id},change:function(){this.trigger("change",
this);this._previousAttributes=e.clone(this.attributes);this._changed=false},hasChanged:function(a){if(a)return this._previousAttributes[a]!=this.attributes[a];return this._changed},changedAttributes:function(a){a||(a=this.attributes);var b=this._previousAttributes,c=false,d;for(d in a)if(!e.isEqual(b[d],a[d])){c=c||{};c[d]=a[d]}return c},previous:function(a){if(!a||!this._previousAttributes)return null;return this._previousAttributes[a]},previousAttributes:function(){return e.clone(this._previousAttributes)}});
f.Collection=function(a,b){b||(b={});if(b.comparator){this.comparator=b.comparator;delete b.comparator}this._boundOnModelEvent=e.bind(this._onModelEvent,this);this._reset();a&&this.refresh(a,{silent:true});this.initialize&&this.initialize(a,b)};e.extend(f.Collection.prototype,f.Events,{model:f.Model,add:function(a,b){if(e.isArray(a))for(var c=0,d=a.length;c<d;c++)this._add(a[c],b);else this._add(a,b);return this},remove:function(a,b){if(e.isArray(a))for(var c=0,d=a.length;c<d;c++)this._remove(a[c],
b);else this._remove(a,b);return this},get:function(a){return a&&this._byId[a.id!=null?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");this.models=this.sortBy(this.comparator);a.silent||this.trigger("refresh",this);return this},pluck:function(a){return e.map(this.models,function(b){return b.get(a)})},refresh:function(a,b){a||(a=[]);b||(b={});this._reset();
this.add(a,{silent:true});b.silent||this.trigger("refresh",this);return this},fetch:function(a){a||(a={});var b=this,c=a.error&&e.bind(a.error,null,b);f.sync("read",this,function(d){b.refresh(d.models);a.success&&a.success(b,d)},c);return this},create:function(a,b){b||(b={});a instanceof f.Model||(a=new this.model(a));a.collection=this;return a.save(null,{success:function(c){a.collection.add(a);b.success&&b.success(a,c)},error:b.error})},_reset:function(){this.length=0;this.models=[];this._byId={};
this._byCid={}},_add:function(a,b){b||(b={});a instanceof f.Model||(a=new this.model(a));var c=this.getByCid(a);if(c)throw Error(["Can't add the same model to a set twice",c.id]);this._byId[a.id]=a;this._byCid[a.cid]=a;a.collection=this;this.models.splice(this.comparator?this.sortedIndex(a,this.comparator):this.length,0,a);a.bind("all",this._boundOnModelEvent);this.length++;b.silent||this.trigger("add",a);return a},_remove:function(a,b){b||(b={});a=this.getByCid(a);if(!a)return null;delete this._byId[a.id];
delete this._byCid[a.cid];delete a.collection;this.models.splice(this.indexOf(a),1);a.unbind("all",this._boundOnModelEvent);this.length--;b.silent||this.trigger("remove",a);return a},_onModelEvent:function(a,b,c){switch(a){case "change":if(b.hasChanged("id")){delete this._byId[b.previous("id")];this._byId[b.id]=b}this.trigger("change",b);break;case "error":this.trigger("error",b,c)}}});e.each(["forEach","each","map","reduce","reduceRight","find","detect","filter","select","reject","every","all","some",
"any","include","invoke","max","min","sortBy","sortedIndex","toArray","size","first","rest","last","without","indexOf","lastIndexOf","isEmpty"],function(a){f.Collection.prototype[a]=function(){return e[a].apply(e,[this.models].concat(e.toArray(arguments)))}});f.View=function(a){this._configure(a||{});if(this.options.el)this.el=this.options.el;else{var b={};if(this.id)b.id=this.id;if(this.className)b.className=this.className;this.el=this.make(this.tagName,b)}this.initialize&&this.initialize(a)};var k=
function(a){return h(a,this.el)},l=/^(\w+)\s*(.*)$/;e.extend(f.View.prototype,{tagName:"div",$:k,jQuery:k,render:function(){return this},make:function(a,b,c){a=document.createElement(a);b&&h(a).attr(b);c&&h(a).html(c);return a},handleEvents:function(a){h(this.el).unbind();if(!(a||(a=this.events)))return this;for(var b in a){var c=a[b],d=b.match(l),g=d[1];d=d[2];c=e.bind(this[c],this);d===""||g=="change"?h(this.el).bind(g,c):h(this.el).delegate(d,g,c)}return this},_configure:function(a){if(this.options)a=
e.extend({},this.options,a);if(a.model)this.model=a.model;if(a.collection)this.collection=a.collection;if(a.id)this.id=a.id;if(a.className)this.className=a.className;if(a.tagName)this.tagName=a.tagName;this.options=a}});var n=f.Model.extend=f.Collection.extend=f.View.extend=function(a,b){var c=m(this,a,b);c.extend=n;return c},o={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};f.sync=function(a,b,c,d){var g=a==="create"||a==="update"?{model:JSON.stringify(b)}:{};a=o[a];if(f.emulateHttp&&(a===
"PUT"||a==="DELETE")){g._method=a;a="POST"}h.ajax({url:j(b),type:a,data:g,dataType:"json",success:c,error:d})};var m=function(a,b,c){var d;d=b.hasOwnProperty("constructor")?b.constructor:function(){return a.apply(this,arguments)};var g=function(){};g.prototype=a.prototype;d.prototype=new g;e.extend(d.prototype,b);c&&e.extend(d,c);return d.prototype.constructor=d},j=function(a){if(!(a&&a.url))throw Error("A 'url' property or function must be specified");return e.isFunction(a.url)?a.url():a.url}})();
this.change();return this},unset:function(a,b){b||(b={});var c=this.attributes[a];delete this.attributes[a];if(!b.silent){this._changed=true;this.trigger("change:"+a,this);this.change()}return c},fetch:function(a){a||(a={});var b=this,c=a.error&&e.bind(a.error,null,b);f.sync("read",this,function(d){if(!b.set(b.parse(d),a))return false;a.success&&a.success(b,d)},c);return this},save:function(a,b){a||(a={});b||(b={});if(!this.set(a,b))return false;var c=this,d=b.error&&e.bind(b.error,null,c),g=this.isNew()?
"create":"update";f.sync(g,this,function(i){if(!c.set(c.parse(i),b))return false;b.success&&b.success(c,i)},d);return this},destroy:function(a){a||(a={});var b=this,c=a.error&&e.bind(a.error,null,b);f.sync("delete",this,function(d){b.collection&&b.collection.remove(b);a.success&&a.success(b,d)},c);return this},url:function(){var a=j(this.collection);if(this.isNew())return a;return a+"/"+this.id},parse:function(a){return a},clone:function(){return new this.constructor(this)},isNew:function(){return!this.id},
change:function(){this.trigger("change",this);this._previousAttributes=e.clone(this.attributes);this._changed=false},hasChanged:function(a){if(a)return this._previousAttributes[a]!=this.attributes[a];return this._changed},changedAttributes:function(a){a||(a=this.attributes);var b=this._previousAttributes,c=false,d;for(d in a)if(!e.isEqual(b[d],a[d])){c=c||{};c[d]=a[d]}return c},previous:function(a){if(!a||!this._previousAttributes)return null;return this._previousAttributes[a]},previousAttributes:function(){return e.clone(this._previousAttributes)}});
f.Collection=function(a,b){b||(b={});if(b.comparator){this.comparator=b.comparator;delete b.comparator}this._boundOnModelEvent=e.bind(this._onModelEvent,this);this._reset();a&&this.refresh(a,{silent:true});this.initialize&&this.initialize(a,b)};e.extend(f.Collection.prototype,f.Events,{model:f.Model,toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,b){if(e.isArray(a))for(var c=0,d=a.length;c<d;c++)this._add(a[c],b);else this._add(a,b);return this},remove:function(a,
b){if(e.isArray(a))for(var c=0,d=a.length;c<d;c++)this._remove(a[c],b);else this._remove(a,b);return this},get:function(a){return a&&this._byId[a.id!=null?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");this.models=this.sortBy(this.comparator);a.silent||this.trigger("refresh",this);return this},pluck:function(a){return e.map(this.models,function(b){return b.get(a)})},
refresh:function(a,b){a||(a=[]);b||(b={});this._reset();this.add(a,{silent:true});b.silent||this.trigger("refresh",this);return this},fetch:function(a){a||(a={});var b=this,c=a.error&&e.bind(a.error,null,b);f.sync("read",this,function(d){b.refresh(b.parse(d));a.success&&a.success(b,d)},c);return this},create:function(a,b){b||(b={});a instanceof f.Model||(a=new this.model(a));var c=a.collection=this;return a.save(null,{success:function(d,g){c.add(d);b.success&&b.success(d,g)},error:b.error})},parse:function(a){return a},
chain:function(){return e(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_add:function(a,b){b||(b={});a instanceof f.Model||(a=new this.model(a));var c=this.getByCid(a);if(c)throw Error(["Can't add the same model to a set twice",c.id]);this._byId[a.id]=a;this._byCid[a.cid]=a;a.collection=this;this.models.splice(this.comparator?this.sortedIndex(a,this.comparator):this.length,0,a);a.bind("all",this._boundOnModelEvent);this.length++;b.silent||this.trigger("add",
a);return a},_remove:function(a,b){b||(b={});a=this.getByCid(a);if(!a)return null;delete this._byId[a.id];delete this._byCid[a.cid];delete a.collection;this.models.splice(this.indexOf(a),1);a.unbind("all",this._boundOnModelEvent);this.length--;b.silent||this.trigger("remove",a);return a},_onModelEvent:function(a,b){if(a==="change:id"){delete this._byId[b.previous("id")];this._byId[b.id]=b}this.trigger.apply(this,arguments)}});e.each(["forEach","each","map","reduce","reduceRight","find","detect","filter",
"select","reject","every","all","some","any","include","invoke","max","min","sortBy","sortedIndex","toArray","size","first","rest","last","without","indexOf","lastIndexOf","isEmpty"],function(a){f.Collection.prototype[a]=function(){return e[a].apply(e,[this.models].concat(e.toArray(arguments)))}});f.View=function(a){this._configure(a||{});this._ensureElement();this.delegateEvents();this.initialize&&this.initialize(a)};var k=function(a){return h(a,this.el)},l=/^(\w+)\s*(.*)$/;e.extend(f.View.prototype,
{tagName:"div",$:k,jQuery:k,render:function(){return this},make:function(a,b,c){a=document.createElement(a);b&&h(a).attr(b);c&&h(a).html(c);return a},delegateEvents:function(a){if(!(a||(a=this.events)))return this;h(this.el).unbind();for(var b in a){var c=a[b],d=b.match(l),g=d[1];d=d[2];c=e.bind(this[c],this);d===""?h(this.el).bind(g,c):h(this.el).delegate(d,g,c)}return this},_configure:function(a){if(this.options)a=e.extend({},this.options,a);if(a.model)this.model=a.model;if(a.collection)this.collection=
a.collection;if(a.el)this.el=a.el;if(a.id)this.id=a.id;if(a.className)this.className=a.className;if(a.tagName)this.tagName=a.tagName;this.options=a},_ensureElement:function(){if(!this.el){var a={};if(this.id)a.id=this.id;if(this.className)a.className=this.className;this.el=this.make(this.tagName,a)}}});var n=f.Model.extend=f.Collection.extend=f.View.extend=function(a,b){var c=m(this,a,b);c.extend=n;return c},o={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};f.sync=function(a,b,c,d){var g=
a==="create"||a==="update"?{model:JSON.stringify(b)}:{};a=o[a];if(f.emulateHttp&&(a==="PUT"||a==="DELETE")){g._method=a;a="POST"}h.ajax({url:j(b),type:a,data:g,dataType:"json",success:c,error:d})};var m=function(a,b,c){var d;d=b.hasOwnProperty("constructor")?b.constructor:function(){return a.apply(this,arguments)};var g=function(){};g.prototype=a.prototype;d.prototype=new g;e.extend(d.prototype,b);c&&e.extend(d,c);return d.prototype.constructor=d},j=function(a){if(!(a&&a.url))throw Error("A 'url' property or function must be specified");
return e.isFunction(a.url)?a.url():a.url}})();

View File

@@ -18,7 +18,7 @@
}
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '0.1.2';
Backbone.VERSION = '0.2.0';
// Require Underscore, if we're on the server, and it's not already present.
var _ = this._;
@@ -198,7 +198,7 @@
options || (options = {});
var model = this;
var success = function(resp) {
if (!model.set(resp.model, options)) return false;
if (!model.set(model.parse(resp), options)) return false;
if (options.success) options.success(model, resp);
};
var error = options.error && _.bind(options.error, null, model);
@@ -215,7 +215,7 @@
if (!this.set(attrs, options)) return false;
var model = this;
var success = function(resp) {
if (!model.set(resp.model, options)) return false;
if (!model.set(model.parse(resp), options)) return false;
if (options.success) options.success(model, resp);
};
var error = options.error && _.bind(options.error, null, model);
@@ -247,6 +247,12 @@
return base + '/' + this.id;
},
// **parse** converts a response into the hash of attributes to be `set` on
// the model. The default implementation is just to pass the response along.
parse : function(resp) {
return resp;
},
// Create a new model with identical attributes to this one.
clone : function() {
return new this.constructor(this);
@@ -410,7 +416,7 @@
options || (options = {});
var collection = this;
var success = function(resp) {
collection.refresh(resp.models);
collection.refresh(collection.parse(resp));
if (options.success) options.success(collection, resp);
};
var error = options.error && _.bind(options.error, null, collection);
@@ -431,6 +437,12 @@
return model.save(null, {success : success, error : options.error});
},
// **parse** converts a response into a list of models to be added to the
// collection. The default implementation is just to pass it through.
parse : function(resp) {
return resp;
},
// Proxy to _'s chain. Can't be proxied the same way the rest of the
// underscore methods are proxied because it relies on the underscore
// constructor.
@@ -483,20 +495,14 @@
},
// Internal method called every time a model in the set fires an event.
// Sets need to update their indexes when models change ids.
_onModelEvent : function(ev, model, error) {
switch (ev) {
case 'change':
if (model.hasChanged('id')) {
delete this._byId[model.previous('id')];
this._byId[model.id] = model;
}
this.trigger('change', model);
break;
case 'error':
this.trigger('error', model, error);
break;
// Sets need to update their indexes when models change ids. All other
// events simply proxy through.
_onModelEvent : function(ev, model) {
if (ev === 'change:id') {
delete this._byId[model.previous('id')];
this._byId[model.id] = model;
}
this.trigger.apply(this, arguments);
}
});
@@ -522,6 +528,7 @@
Backbone.View = function(options) {
this._configure(options || {});
this._ensureElement();
this.delegateEvents();
if (this.initialize) this.initialize(options);
};
@@ -532,7 +539,7 @@
return $(selector, this.el);
};
// Cached regex to split keys for `handleEvents`.
// Cached regex to split keys for `delegate`.
var eventSplitter = /^(\w+)\s*(.*)$/;
// Set up all inheritable **Backbone.View** properties and methods.
@@ -576,17 +583,17 @@
// pairs. Callbacks will be bound to the view, with `this` set properly.
// Uses jQuery event delegation for efficiency.
// Omitting the selector binds the event to `this.el`.
// `"change"` events are not delegated through the view because IE does not
// bubble change events at all.
handleEvents : function(events) {
$(this.el).unbind();
// This only works for delegate-able events: not `focus`, `blur`, and
// not `change`, `submit`, and `reset` in Internet Explorer.
delegateEvents : function(events) {
if (!(events || (events = this.events))) return this;
$(this.el).unbind();
for (var key in events) {
var methodName = events[key];
var match = key.match(eventSplitter);
var eventName = match[1], selector = match[2];
var method = _.bind(this[methodName], this);
if (selector === '' || eventName == 'change') {
if (selector === '') {
$(this.el).bind(eventName, method);
} else {
$(this.el).delegate(selector, eventName, method);

View File

@@ -8,7 +8,7 @@ be attached to this. Exported for both CommonJS and the browser.</p>
<span class="nx">Backbone</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">Backbone</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">Backbone</span> <span class="o">=</span> <span class="p">{};</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>Current version of the library. Keep in sync with <code>package.json</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">VERSION</span> <span class="o">=</span> <span class="s1">&#39;0.1.2&#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Require Underscore, if we're on the server, and it's not already present.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>Current version of the library. Keep in sync with <code>package.json</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">VERSION</span> <span class="o">=</span> <span class="s1">&#39;0.2.0&#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Require Underscore, if we're on the server, and it's not already present.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">require</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">))</span> <span class="nx">_</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;underscore&quot;</span><span class="p">).</span><span class="nx">_</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>For Backbone's purposes, jQuery owns the <code>$</code> variable.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">$</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">jQuery</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Turn on <code>emulateHttp</code> to fake <code>"PUT"</code> and <code>"DELETE"</code> requests via
the <code>_method</code> parameter.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">emulateHttp</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <h2>Backbone.Events</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>A module that can be mixed in to <em>any object</em> in order to provide it with
custom events. You may <code>bind</code> or <code>unbind</code> a callback function to an event;
@@ -119,7 +119,7 @@ triggering a <code>"change"</code> event.</p> </td> <td
<span class="nx">options</span> <span class="o">||</span> <span class="p">(</span><span class="nx">options</span> <span class="o">=</span> <span class="p">{});</span>
<span class="kd">var</span> <span class="nx">model</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">success</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">model</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">model</span><span class="p">,</span> <span class="nx">options</span><span class="p">))</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">model</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">model</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">resp</span><span class="p">),</span> <span class="nx">options</span><span class="p">))</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">)</span> <span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">(</span><span class="nx">model</span><span class="p">,</span> <span class="nx">resp</span><span class="p">);</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">error</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">error</span> <span class="o">&amp;&amp;</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">error</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">model</span><span class="p">);</span>
@@ -133,7 +133,7 @@ state will be <code>set</code> again.</p> </td> <td clas
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">attrs</span><span class="p">,</span> <span class="nx">options</span><span class="p">))</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">model</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">success</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">model</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">model</span><span class="p">,</span> <span class="nx">options</span><span class="p">))</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">model</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">model</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">resp</span><span class="p">),</span> <span class="nx">options</span><span class="p">))</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">)</span> <span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">(</span><span class="nx">model</span><span class="p">,</span> <span class="nx">resp</span><span class="p">);</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">error</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">error</span> <span class="o">&amp;&amp;</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">error</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">model</span><span class="p">);</span>
@@ -157,21 +157,24 @@ that will be called.</p> </td> <td class="code">
<span class="kd">var</span> <span class="nx">base</span> <span class="o">=</span> <span class="nx">getUrl</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">collection</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">isNew</span><span class="p">())</span> <span class="k">return</span> <span class="nx">base</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">base</span> <span class="o">+</span> <span class="s1">&#39;/&#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>Create a new model with identical attributes to this one.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">clone</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p><strong>parse</strong> converts a response into the hash of attributes to be <code>set</code> on
the model. The default implementation is just to pass the response along.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">parse</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">resp</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>Create a new model with identical attributes to this one.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">clone</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="k">this</span><span class="p">.</span><span class="nx">constructor</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>A model is new if it has never been saved to the server, and has a negative
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <p>A model is new if it has never been saved to the server, and has a negative
ID.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">isNew</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <p>Call this method to fire manually fire a <code>change</code> event for this model.
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</a> </div> <p>Call this method to fire manually fire a <code>change</code> event for this model.
Calling this will cause all objects observing the model to update.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">change</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;change&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_previousAttributes</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">clone</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">attributes</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_changed</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</a> </div> <p>Determine if the model has changed since the last <code>"change"</code> event.
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <p>Determine if the model has changed since the last <code>"change"</code> event.
If you specify an attribute name, determine if that attribute has changed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">hasChanged</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">attr</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">attr</span><span class="p">)</span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_previousAttributes</span><span class="p">[</span><span class="nx">attr</span><span class="p">]</span> <span class="o">!=</span> <span class="k">this</span><span class="p">.</span><span class="nx">attributes</span><span class="p">[</span><span class="nx">attr</span><span class="p">];</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_changed</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <p>Return an object containing all the attributes that have changed, or false
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</a> </div> <p>Return an object containing all the attributes that have changed, or false
if there are no changed attributes. Useful for determining what parts of a
view need to be updated and/or what attributes need to be persisted to
the server.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">changedAttributes</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">now</span><span class="p">)</span> <span class="p">{</span>
@@ -185,16 +188,16 @@ the server.</p> </td> <td class="code"> <d
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">changed</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</a> </div> <p>Get the previous value of an attribute, recorded at the time the last
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <p>Get the previous value of an attribute, recorded at the time the last
<code>"change"</code> event was fired.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">previous</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">attr</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">attr</span> <span class="o">||</span> <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">_previousAttributes</span><span class="p">)</span> <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_previousAttributes</span><span class="p">[</span><span class="nx">attr</span><span class="p">];</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <p>Get all of the attributes of the model at the time of the previous
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</a> </div> <p>Get all of the attributes of the model at the time of the previous
<code>"change"</code> event.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">previousAttributes</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">clone</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_previousAttributes</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</a> </div> <h2>Backbone.Collection</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <p>Provides a standard collection class for our sets of models, ordered
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <h2>Backbone.Collection</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>Provides a standard collection class for our sets of models, ordered
or unordered. If a <code>comparator</code> is specified, the Collection will maintain
its models in sort order, as they're added and removed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">options</span> <span class="o">||</span> <span class="p">(</span><span class="nx">options</span> <span class="o">=</span> <span class="p">{});</span>
@@ -206,8 +209,11 @@ its models in sort order, as they're added and removed.</p> </td>
<span class="k">this</span><span class="p">.</span><span class="nx">_reset</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">models</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">refresh</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="p">{</span><span class="nx">silent</span><span class="o">:</span> <span class="kc">true</span><span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">initialize</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">initialize</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>Define the Collection's inheritable methods.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Events</span><span class="p">,</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>The default model for a collection is just a <strong>Backbone.Model</strong>.
This should be overridden in most cases.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">model</span> <span class="o">:</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>Add a model, or list of models to the set. Pass <strong>silent</strong> to avoid
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>Define the Collection's inheritable methods.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Events</span><span class="p">,</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>The default model for a collection is just a <strong>Backbone.Model</strong>.
This should be overridden in most cases.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">model</span> <span class="o">:</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <p>The JSON representation of a Collection is an array of the
models' attributes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">toJSON</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">){</span> <span class="k">return</span> <span class="nx">model</span><span class="p">.</span><span class="nx">toJSON</span><span class="p">();</span> <span class="p">});</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <p>Add a model, or list of models to the set. Pass <strong>silent</strong> to avoid
firing the <code>added</code> event for every new model.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">add</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">models</span><span class="p">))</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">models</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
@@ -217,7 +223,7 @@ firing the <code>added</code> event for every new model.</p> </td>
<span class="k">this</span><span class="p">.</span><span class="nx">_add</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <p>Remove a model, or a list of models from the set. Pass silent to avoid
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <p>Remove a model, or a list of models from the set. Pass silent to avoid
firing the <code>removed</code> event for every model removed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">remove</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">models</span><span class="p">))</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">models</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
@@ -227,22 +233,22 @@ firing the <code>removed</code> event for every model removed.</p> <
<span class="k">this</span><span class="p">.</span><span class="nx">_remove</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <p>Get a model from the set by id.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">get</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</a> </div> <p>Get a model from the set by id.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">get</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">id</span> <span class="o">&amp;&amp;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_byId</span><span class="p">[</span><span class="nx">id</span><span class="p">.</span><span class="nx">id</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">?</span> <span class="nx">id</span><span class="p">.</span><span class="nx">id</span> <span class="o">:</span> <span class="nx">id</span><span class="p">];</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <p>Get a model from the set by client id.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">getByCid</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">cid</span><span class="p">)</span> <span class="p">{</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <p>Get a model from the set by client id.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">getByCid</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">cid</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">cid</span> <span class="o">&amp;&amp;</span> <span class="k">this</span><span class="p">.</span><span class="nx">_byCid</span><span class="p">[</span><span class="nx">cid</span><span class="p">.</span><span class="nx">cid</span> <span class="o">||</span> <span class="nx">cid</span><span class="p">];</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</a> </div> <p>Get the model at the given index.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">at</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</a> </div> <p>Get the model at the given index.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">at</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">models</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <p>Force the collection to re-sort itself. You don't need to call this under normal
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <p>Force the collection to re-sort itself. You don't need to call this under normal
circumstances, as the set will maintain sort order as each item is added.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">sort</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">options</span> <span class="o">||</span> <span class="p">(</span><span class="nx">options</span> <span class="o">=</span> <span class="p">{});</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">comparator</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;Cannot sort a set without a comparator&#39;</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">models</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">sortBy</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">comparator</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">silent</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;refresh&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</a> </div> <p>Pluck an attribute from each model in the collection.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">pluck</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">attr</span><span class="p">)</span> <span class="p">{</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>Pluck an attribute from each model in the collection.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">pluck</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">attr</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">models</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">){</span> <span class="k">return</span> <span class="nx">model</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">attr</span><span class="p">);</span> <span class="p">});</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <p>When you have more items than you want to add or remove individually,
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>When you have more items than you want to add or remove individually,
you can refresh the entire set with a new list of models, without firing
any <code>added</code> or <code>removed</code> events. Fires <code>refresh</code> when finished.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">refresh</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">models</span> <span class="o">||</span> <span class="p">(</span><span class="nx">models</span> <span class="o">=</span> <span class="p">[]);</span>
@@ -251,33 +257,40 @@ any <code>added</code> or <code>removed</code> events. Fires <code>refresh</code
<span class="k">this</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">models</span><span class="p">,</span> <span class="p">{</span><span class="nx">silent</span><span class="o">:</span> <span class="kc">true</span><span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">silent</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;refresh&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>Fetch the default set of models for this collection, refreshing the
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>Fetch the default set of models for this collection, refreshing the
collection when they arrive.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">fetch</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">options</span> <span class="o">||</span> <span class="p">(</span><span class="nx">options</span> <span class="o">=</span> <span class="p">{});</span>
<span class="kd">var</span> <span class="nx">collection</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">success</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">collection</span><span class="p">.</span><span class="nx">refresh</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">models</span><span class="p">);</span>
<span class="nx">collection</span><span class="p">.</span><span class="nx">refresh</span><span class="p">(</span><span class="nx">collection</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">resp</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">)</span> <span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">(</span><span class="nx">collection</span><span class="p">,</span> <span class="nx">resp</span><span class="p">);</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">error</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">error</span> <span class="o">&amp;&amp;</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">error</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">collection</span><span class="p">);</span>
<span class="nx">Backbone</span><span class="p">.</span><span class="nx">sync</span><span class="p">(</span><span class="s1">&#39;read&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="nx">success</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>Create a new instance of a model in this collection. After the model
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>Create a new instance of a model in this collection. After the model
has been created on the server, it will be added to the collection.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">create</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">options</span> <span class="o">||</span> <span class="p">(</span><span class="nx">options</span> <span class="o">=</span> <span class="p">{});</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">model</span> <span class="k">instanceof</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">))</span> <span class="nx">model</span> <span class="o">=</span> <span class="k">new</span> <span class="k">this</span><span class="p">.</span><span class="nx">model</span><span class="p">(</span><span class="nx">model</span><span class="p">);</span>
<span class="nx">model</span><span class="p">.</span><span class="nx">collection</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">success</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">model</span><span class="p">.</span><span class="nx">collection</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">model</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">)</span> <span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">(</span><span class="nx">model</span><span class="p">,</span> <span class="nx">resp</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">coll</span> <span class="o">=</span> <span class="nx">model</span><span class="p">.</span><span class="nx">collection</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">success</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">nextModel</span><span class="p">,</span> <span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">coll</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">nextModel</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">)</span> <span class="nx">options</span><span class="p">.</span><span class="nx">success</span><span class="p">(</span><span class="nx">nextModel</span><span class="p">,</span> <span class="nx">resp</span><span class="p">);</span>
<span class="p">};</span>
<span class="k">return</span> <span class="nx">model</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span><span class="nx">success</span> <span class="o">:</span> <span class="nx">success</span><span class="p">,</span> <span class="nx">error</span> <span class="o">:</span> <span class="nx">options</span><span class="p">.</span><span class="nx">error</span><span class="p">});</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>Reset all internal state. Called when the collection is refreshed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_reset</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <p><strong>parse</strong> converts a response into a list of models to be added to the
collection. The default implementation is just to pass it through.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">parse</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">resp</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</a> </div> <p>Proxy to _'s chain. Can't be proxied the same way the rest of the
underscore methods are proxied because it relies on the underscore
constructor.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">chain</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">models</span><span class="p">).</span><span class="nx">chain</span><span class="p">();</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">&#182;</a> </div> <p>Reset all internal state. Called when the collection is refreshed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_reset</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">length</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">models</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_byId</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_byCid</span> <span class="o">=</span> <span class="p">{};</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>Internal implementation of adding a single model to the set, updating
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">&#182;</a> </div> <p>Internal implementation of adding a single model to the set, updating
hash indexes for <code>id</code> and <code>cid</code> lookups.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_add</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">options</span> <span class="o">||</span> <span class="p">(</span><span class="nx">options</span> <span class="o">=</span> <span class="p">{});</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">model</span> <span class="k">instanceof</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">))</span> <span class="p">{</span>
@@ -294,7 +307,7 @@ hash indexes for <code>id</code> and <code>cid</code> lookups.</p> <
<span class="k">this</span><span class="p">.</span><span class="nx">length</span><span class="o">++</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">silent</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;add&#39;</span><span class="p">,</span> <span class="nx">model</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">model</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <p>Internal implementation of removing a single model from the set, updating
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">&#182;</a> </div> <p>Internal implementation of removing a single model from the set, updating
hash indexes for <code>id</code> and <code>cid</code> lookups.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_remove</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">model</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">options</span> <span class="o">||</span> <span class="p">(</span><span class="nx">options</span> <span class="o">=</span> <span class="p">{});</span>
<span class="nx">model</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getByCid</span><span class="p">(</span><span class="nx">model</span><span class="p">);</span>
@@ -307,51 +320,39 @@ hash indexes for <code>id</code> and <code>cid</code> lookups.</p> <
<span class="k">this</span><span class="p">.</span><span class="nx">length</span><span class="o">--</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">silent</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;remove&#39;</span><span class="p">,</span> <span class="nx">model</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">model</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</a> </div> <p>Internal method called every time a model in the set fires an event.
Sets need to update their indexes when models change ids.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_onModelEvent</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">ev</span><span class="p">,</span> <span class="nx">model</span><span class="p">,</span> <span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="nx">ev</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="s1">&#39;change&#39;</span><span class="o">:</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">model</span><span class="p">.</span><span class="nx">hasChanged</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">))</span> <span class="p">{</span>
<span class="k">delete</span> <span class="k">this</span><span class="p">.</span><span class="nx">_byId</span><span class="p">[</span><span class="nx">model</span><span class="p">.</span><span class="nx">previous</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)];</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_byId</span><span class="p">[</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">]</span> <span class="o">=</span> <span class="nx">model</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">this</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;change&#39;</span><span class="p">,</span> <span class="nx">model</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="s1">&#39;error&#39;</span><span class="o">:</span>
<span class="k">this</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;error&#39;</span><span class="p">,</span> <span class="nx">model</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <p>Internal method called every time a model in the set fires an event.
Sets need to update their indexes when models change ids. All other
events simply proxy through.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_onModelEvent</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">ev</span><span class="p">,</span> <span class="nx">model</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">ev</span> <span class="o">===</span> <span class="s1">&#39;change:id&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">delete</span> <span class="k">this</span><span class="p">.</span><span class="nx">_byId</span><span class="p">[</span><span class="nx">model</span><span class="p">.</span><span class="nx">previous</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)];</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_byId</span><span class="p">[</span><span class="nx">model</span><span class="p">.</span><span class="nx">id</span><span class="p">]</span> <span class="o">=</span> <span class="nx">model</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">this</span><span class="p">.</span><span class="nx">trigger</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">&#182;</a> </div> <p>Underscore methods that we want to implement on the Collection.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">methods</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;forEach&#39;</span><span class="p">,</span> <span class="s1">&#39;each&#39;</span><span class="p">,</span> <span class="s1">&#39;map&#39;</span><span class="p">,</span> <span class="s1">&#39;reduce&#39;</span><span class="p">,</span> <span class="s1">&#39;reduceRight&#39;</span><span class="p">,</span> <span class="s1">&#39;find&#39;</span><span class="p">,</span> <span class="s1">&#39;detect&#39;</span><span class="p">,</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>Underscore methods that we want to implement on the Collection.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">methods</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;forEach&#39;</span><span class="p">,</span> <span class="s1">&#39;each&#39;</span><span class="p">,</span> <span class="s1">&#39;map&#39;</span><span class="p">,</span> <span class="s1">&#39;reduce&#39;</span><span class="p">,</span> <span class="s1">&#39;reduceRight&#39;</span><span class="p">,</span> <span class="s1">&#39;find&#39;</span><span class="p">,</span> <span class="s1">&#39;detect&#39;</span><span class="p">,</span>
<span class="s1">&#39;filter&#39;</span><span class="p">,</span> <span class="s1">&#39;select&#39;</span><span class="p">,</span> <span class="s1">&#39;reject&#39;</span><span class="p">,</span> <span class="s1">&#39;every&#39;</span><span class="p">,</span> <span class="s1">&#39;all&#39;</span><span class="p">,</span> <span class="s1">&#39;some&#39;</span><span class="p">,</span> <span class="s1">&#39;any&#39;</span><span class="p">,</span> <span class="s1">&#39;include&#39;</span><span class="p">,</span>
<span class="s1">&#39;invoke&#39;</span><span class="p">,</span> <span class="s1">&#39;max&#39;</span><span class="p">,</span> <span class="s1">&#39;min&#39;</span><span class="p">,</span> <span class="s1">&#39;sortBy&#39;</span><span class="p">,</span> <span class="s1">&#39;sortedIndex&#39;</span><span class="p">,</span> <span class="s1">&#39;toArray&#39;</span><span class="p">,</span> <span class="s1">&#39;size&#39;</span><span class="p">,</span>
<span class="s1">&#39;first&#39;</span><span class="p">,</span> <span class="s1">&#39;rest&#39;</span><span class="p">,</span> <span class="s1">&#39;last&#39;</span><span class="p">,</span> <span class="s1">&#39;without&#39;</span><span class="p">,</span> <span class="s1">&#39;indexOf&#39;</span><span class="p">,</span> <span class="s1">&#39;lastIndexOf&#39;</span><span class="p">,</span> <span class="s1">&#39;isEmpty&#39;</span><span class="p">];</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">&#182;</a> </div> <p>Mix in each Underscore method as a proxy to <code>Collection#models</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">methods</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
<span class="s1">&#39;first&#39;</span><span class="p">,</span> <span class="s1">&#39;rest&#39;</span><span class="p">,</span> <span class="s1">&#39;last&#39;</span><span class="p">,</span> <span class="s1">&#39;without&#39;</span><span class="p">,</span> <span class="s1">&#39;indexOf&#39;</span><span class="p">,</span> <span class="s1">&#39;lastIndexOf&#39;</span><span class="p">,</span> <span class="s1">&#39;isEmpty&#39;</span><span class="p">];</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">&#182;</a> </div> <p>Mix in each Underscore method as a proxy to <code>Collection#models</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">methods</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">prototype</span><span class="p">[</span><span class="nx">method</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">[</span><span class="nx">method</span><span class="p">].</span><span class="nx">apply</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">models</span><span class="p">].</span><span class="nx">concat</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">toArray</span><span class="p">(</span><span class="nx">arguments</span><span class="p">)));</span>
<span class="p">};</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">&#182;</a> </div> <h2>Backbone.View</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <p>Creating a Backbone.View creates its initial element outside of the DOM,
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">&#182;</a> </div> <h2>Backbone.View</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">&#182;</a> </div> <p>Creating a Backbone.View creates its initial element outside of the DOM,
if an existing element is not provided...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_configure</span><span class="p">(</span><span class="nx">options</span> <span class="o">||</span> <span class="p">{});</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">el</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">el</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">.</span><span class="nx">el</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">attrs</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span> <span class="nx">attrs</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">className</span><span class="p">)</span> <span class="nx">attrs</span><span class="p">.</span><span class="nx">className</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">className</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">el</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">make</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">tagName</span><span class="p">,</span> <span class="nx">attrs</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_ensureElement</span><span class="p">();</span>
<span class="k">this</span><span class="p">.</span><span class="nx">delegateEvents</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">initialize</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">initialize</span><span class="p">(</span><span class="nx">options</span><span class="p">);</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>jQuery lookup, scoped to DOM elements within the current view.
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">&#182;</a> </div> <p>jQuery lookup, scoped to DOM elements within the current view.
This should be prefered to global jQuery lookups, if you're dealing with
a specific view.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">jQueryDelegate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">selector</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">$</span><span class="p">(</span><span class="nx">selector</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">);</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">&#182;</a> </div> <p>Cached regex to split keys for <code>handleEvents</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">eventSplitter</span> <span class="o">=</span> <span class="sr">/^(\w+)\s*(.*)$/</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">&#182;</a> </div> <p>Set up all inheritable <strong>Backbone.View</strong> properties and methods.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">&#182;</a> </div> <p>The default <code>tagName</code> of a View's element is <code>"div"</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">tagName</span> <span class="o">:</span> <span class="s1">&#39;div&#39;</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">&#182;</a> </div> <p>Attach the jQuery function as the <code>$</code> and <code>jQuery</code> properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">$</span> <span class="o">:</span> <span class="nx">jQueryDelegate</span><span class="p">,</span>
<span class="nx">jQuery</span> <span class="o">:</span> <span class="nx">jQueryDelegate</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <p><strong>render</strong> is the core function that your view should override, in order
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <p>Cached regex to split keys for <code>delegate</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">eventSplitter</span> <span class="o">=</span> <span class="sr">/^(\w+)\s*(.*)$/</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>Set up all inheritable <strong>Backbone.View</strong> properties and methods.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">&#182;</a> </div> <p>The default <code>tagName</code> of a View's element is <code>"div"</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">tagName</span> <span class="o">:</span> <span class="s1">&#39;div&#39;</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">&#182;</a> </div> <p>Attach the jQuery function as the <code>$</code> and <code>jQuery</code> properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">$</span> <span class="o">:</span> <span class="nx">jQueryDelegate</span><span class="p">,</span>
<span class="nx">jQuery</span> <span class="o">:</span> <span class="nx">jQueryDelegate</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">&#182;</a> </div> <p><strong>render</strong> is the core function that your view should override, in order
to populate its element (<code>this.el</code>), with the appropriate HTML. The
convention is for <strong>render</strong> to always return <code>this</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">render</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>For small amounts of DOM Elements, where a full-blown template isn't
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-70">&#182;</a> </div> <p>For small amounts of DOM Elements, where a full-blown template isn't
needed, use <strong>make</strong> to manufacture elements, one at a time.</p>
<pre><code>var el = this.make('li', {'class': 'row'}, this.model.get('title'));
@@ -360,7 +361,7 @@ needed, use <strong>make</strong> to manufacture elements, one at a time.</p>
<span class="k">if</span> <span class="p">(</span><span class="nx">attributes</span><span class="p">)</span> <span class="nx">$</span><span class="p">(</span><span class="nx">el</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="nx">attributes</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="nx">$</span><span class="p">(</span><span class="nx">el</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">el</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">&#182;</a> </div> <p>Set callbacks, where <code>this.callbacks</code> is a hash of</p>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-71">&#182;</a> </div> <p>Set callbacks, where <code>this.callbacks</code> is a hash of</p>
<p><em>{"event selector": "callback"}</em></p>
@@ -373,44 +374,51 @@ needed, use <strong>make</strong> to manufacture elements, one at a time.</p>
<p>pairs. Callbacks will be bound to the view, with <code>this</code> set properly.
Uses jQuery event delegation for efficiency.
Omitting the selector binds the event to <code>this.el</code>.
<code>"change"</code> events are not delegated through the view because IE does not
bubble change events at all.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">handleEvents</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">events</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">).</span><span class="nx">unbind</span><span class="p">();</span>
This only works for delegate-able events: not <code>focus</code>, <code>blur</code>, and
not <code>change</code>, <code>submit</code>, and <code>reset</code> in Internet Explorer.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">delegateEvents</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">events</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">events</span> <span class="o">||</span> <span class="p">(</span><span class="nx">events</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">)))</span> <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">).</span><span class="nx">unbind</span><span class="p">();</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">events</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">methodName</span> <span class="o">=</span> <span class="nx">events</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">match</span> <span class="o">=</span> <span class="nx">key</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">eventSplitter</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">eventName</span> <span class="o">=</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nx">selector</span> <span class="o">=</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">method</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">[</span><span class="nx">methodName</span><span class="p">],</span> <span class="k">this</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">selector</span> <span class="o">===</span> <span class="s1">&#39;&#39;</span> <span class="o">||</span> <span class="nx">eventName</span> <span class="o">==</span> <span class="s1">&#39;change&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">selector</span> <span class="o">===</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">).</span><span class="nx">bind</span><span class="p">(</span><span class="nx">eventName</span><span class="p">,</span> <span class="nx">method</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">).</span><span class="nx">delegate</span><span class="p">(</span><span class="nx">selector</span><span class="p">,</span> <span class="nx">eventName</span><span class="p">,</span> <span class="nx">method</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">&#182;</a> </div> <p>Performs the initial configuration of a View with a set of options.
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-72">&#182;</a> </div> <p>Performs the initial configuration of a View with a set of options.
Keys with special meaning <em>(model, collection, id, className)</em>, are
attached directly to the view.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_configure</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">)</span> <span class="nx">options</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">({},</span> <span class="k">this</span><span class="p">.</span><span class="nx">options</span><span class="p">,</span> <span class="nx">options</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">model</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">model</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">model</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">collection</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">collection</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">collection</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">el</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">el</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">el</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">className</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">className</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">className</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">tagName</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">tagName</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">tagName</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">options</span> <span class="o">=</span> <span class="nx">options</span><span class="p">;</span>
<span class="p">},</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-73">&#182;</a> </div> <p>Ensure that the View has a DOM element to render into.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_ensureElement</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">attrs</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span> <span class="nx">attrs</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">id</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">className</span><span class="p">)</span> <span class="nx">attrs</span><span class="p">.</span><span class="nx">className</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">className</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">el</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">make</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">tagName</span><span class="p">,</span> <span class="nx">attrs</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">&#182;</a> </div> <p>Set up inheritance for the model, collection, and view.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">extend</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">protoProps</span><span class="p">,</span> <span class="nx">classProps</span><span class="p">)</span> <span class="p">{</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-74">&#182;</a> </div> <p>Set up inheritance for the model, collection, and view.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">extend</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">protoProps</span><span class="p">,</span> <span class="nx">classProps</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">inherits</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">protoProps</span><span class="p">,</span> <span class="nx">classProps</span><span class="p">);</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">extend</span> <span class="o">=</span> <span class="nx">extend</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">child</span><span class="p">;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-70">&#182;</a> </div> <p>Map from CRUD to HTTP for our default <code>Backbone.sync</code> implementation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">methodMap</span> <span class="o">=</span> <span class="p">{</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-75">&#182;</a> </div> <p>Map from CRUD to HTTP for our default <code>Backbone.sync</code> implementation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">methodMap</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">&#39;create&#39;</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
<span class="s1">&#39;update&#39;</span><span class="o">:</span> <span class="s1">&#39;PUT&#39;</span><span class="p">,</span>
<span class="s1">&#39;delete&#39;</span><span class="o">:</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">,</span>
<span class="s1">&#39;read&#39;</span> <span class="o">:</span> <span class="s1">&#39;GET&#39;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-71">&#182;</a> </div> <h2>Backbone.sync</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-72">&#182;</a> </div> <p>Override this function to change the manner in which Backbone persists
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-76">&#182;</a> </div> <h2>Backbone.sync</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-77">&#182;</a> </div> <p>Override this function to change the manner in which Backbone persists
models to the server. You will be passed the type of request, and the
model in question. By default, uses jQuery to make a RESTful Ajax request
to the model's <code>url()</code>. Some possible customizations could be:</p>
@@ -440,7 +448,7 @@ it difficult to read the body of <code>PUT</code> requests.</p> </td
<span class="nx">success</span> <span class="o">:</span> <span class="nx">success</span><span class="p">,</span>
<span class="nx">error</span> <span class="o">:</span> <span class="nx">error</span>
<span class="p">});</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-73">&#182;</a> </div> <h2>Helpers</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-74">&#182;</a> </div> <p>Helper function to correctly set up the prototype chain, for subclasses.
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-78">&#182;</a> </div> <h2>Helpers</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-79">&#182;</a> </div> <p>Helper function to correctly set up the prototype chain, for subclasses.
Similar to <code>goog.inherits</code>, but uses a hash of prototype properties and
class properties to be extended.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">inherits</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">parent</span><span class="p">,</span> <span class="nx">protoProps</span><span class="p">,</span> <span class="nx">classProps</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">child</span><span class="p">;</span>
@@ -456,7 +464,7 @@ class properties to be extended.</p> </td> <td class="co
<span class="k">if</span> <span class="p">(</span><span class="nx">classProps</span><span class="p">)</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">child</span><span class="p">,</span> <span class="nx">classProps</span><span class="p">);</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">constructor</span> <span class="o">=</span> <span class="nx">child</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">child</span><span class="p">;</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-75">&#182;</a> </div> <p>Helper function to get a URL from a Model or Collection as a property
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-80">&#182;</a> </div> <p>Helper function to get a URL from a Model or Collection as a property
or as a function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">getUrl</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">object</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">object</span> <span class="o">&amp;&amp;</span> <span class="nx">object</span><span class="p">.</span><span class="nx">url</span><span class="p">))</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;A &#39;url&#39; property or function must be specified&quot;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">object</span><span class="p">.</span><span class="nx">url</span><span class="p">)</span> <span class="o">?</span> <span class="nx">object</span><span class="p">.</span><span class="nx">url</span><span class="p">()</span> <span class="o">:</span> <span class="nx">object</span><span class="p">.</span><span class="nx">url</span><span class="p">;</span>

View File

@@ -1,38 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Backbone Demo: Todo List</title>
<style>
.todo.complete .todo-content {
text-decoration: line-through;
}
</style>
<script src="../test/vendor/underscore-1.1.0.js"></script>
<script src="../test/vendor/jquery-1.4.2.js"></script>
<script src="../backbone.js"></script>
<script id="todo-template" type="x-ejs">
<input type="checkbox" <%= model.get('completed') ? 'checked' : '' %> />
<span class="todo-content"><%= model.get('content') %></span>
</script>
<script id="edit-template" type="x-ejs">
<input type="text" value="<%= model.get('content') %>" />
<input type="submit" class="update" value="Update" />
</script>
<script id="app-template" type="x-ejs">
<input class="new-task-input" type="text" placeholder="New task..." />
<input class="new-task" type="submit" value="Add" />
<ul class="task-list"></ul>
<input class="clear" type="submit" value="Clear Completed Tasks" />
</script>
<script src="todos.js"></script>
</head>
<body>
</body>
</html>

View File

@@ -1,165 +0,0 @@
// DISCLAIMER: This example is not yet complete, and probably isn't *too*
// helpful for getting a sense of a real-world Backbone application just yet.
// Contributions to it are welcome, but be careful of trying to use it as a
// model.
(function() {
// ### Models
// Our main model. It is simple enough that it doesn't need any prototype
// methods.
window.Task = Backbone.Model.extend({
htmlId : function() {
return "task-" + this.cid;
}
});
// A Collection wrapper for Task instances.
window.TaskCollection = Backbone.Collection.extend({
model: Task,
// Return the list of tasks which are already complete.
complete: function() {
return this.filter(function(task) {
return task.get('complete');
});
}
});
window.Tasks = new TaskCollection;
// ### Views
// The TaskView is a View that handles the rendering and events of a single
// Task instance. You can double click on the task's text to edit it's content
// in a text box and tick the checkbox on or off to mark whether it is
// complete or not.
window.TaskView = Backbone.View.extend({
tagName: "li",
className: "todo",
displayTemplate: _.template($('#todo-template').html()),
editTemplate: _.template($('#edit-template').html()),
events: {
"dblclick span": "edit",
"click input[type=checkbox]": "toggle",
"click input.update": "changed"
},
initialize: function(opts) {
_.bindAll(this, 'setComplete');
this.model.bind('change:complete', this.setComplete);
this.handleEvents(); // Bind the event delegators.
},
// Render (or empty and re-render) this view. If this task is complete,
// make the text have strike through.
render: function() {
$(this.el).html(this.displayTemplate({model: this.model}));
this.el.id = this.model.htmlId();
this.setComplete();
return this;
},
setComplete: function() {
$(this.el).toggleClass('complete', this.model.get('complete'));
},
// Switch this view from display mode in to edit mode. Provide a text input
// to edit this task's content and a submit button to click to save the
// updates.
edit: function() {
$(this.el).html(this.editTemplate({model : this.model}));
},
// Switch back to display mode after being in edit mode. Save the new
// content for the model in the process.
changed: function() {
this.model.set({
content: this.$("input[type=text]").val()
});
this.render();
},
// Event handler for ticking the checkbox. Just toggle whether the task is
// complete or not and let render() take care of strike-through.
toggle: function() {
this.model.set({ complete: !this.model.get("complete") });
}
});
// The TodoListApp is the main view for this application. It handles creation
// of new Tasks, clearing complete tasks, and supervises the individual
// TaskViews.
window.TodoListApp = Backbone.View.extend({
template: _.template($('#app-template').html()),
events: {
"keypress input.new-task-input" : "maybeCreate",
"click input.new-task" : "create",
"click input.clear" : "clear"
},
initialize: function() {
_.bindAll(this, 'addTask', 'removeTask');
this.handleEvents();
Tasks.bind('add', this.addTask);
Tasks.bind('remove', this.removeTask);
},
render: function() {
$(this.el).html(this.template());
this._list = this.$('.task-list');
this._input = this.$(".new-task-input");
return this;
},
addTask: function(task) {
var view = new TaskView({model : task});
this._list.append(view.render().el);
},
removeTask: function(task) {
this.$('#' + task.htmlId()).remove();
},
// Create a new task, add it to the children, and let render() handle
// creating a TaskView for it and displaying it.
create: function() {
var task = new Task({
content: this._input.val(),
complete: false
});
Tasks.add(task);
this._input.val('');
},
maybeCreate: function(e) {
if (e.keyCode == 13) this.create();
},
// Clear out all of the complete tasks and let render() handle removing
// them from the page.
clear: function() {
Tasks.remove(Tasks.complete());
}
});
window.App = new TodoListApp;
// Initialize the app on document ready.
$(document).ready(function() {
$("body").append(App.render().el);
});
}());

View File

@@ -34,6 +34,10 @@
div.toc_title:hover {
text-decoration: underline;
}
#sidebar .version {
font-size: 10px;
font-weight: normal;
}
ul.toc_section {
font-size: 11px;
line-height: 14px;
@@ -67,6 +71,11 @@
margin: 20px 0;
width: 550px;
}
p.warning {
font-size: 12px;
line-height: 18px;
font-style: italic;
}
div.container ul {
list-style: circle;
font-size: 12px;
@@ -111,6 +120,7 @@
font-family: Monaco, Consolas, "Lucida Console", monospace;
font-size: 12px;
line-height: 18px;
font-style: normal;
}
tt {
padding: 0px 3px;
@@ -133,7 +143,7 @@
<div id="sidebar" class="interface">
<a class="toc_title" href="#">
Backbone.js
Backbone.js <span class="version">(0.2.0)</span>
</a>
<a class="toc_title" href="#Introduction">
Introduction
@@ -164,6 +174,7 @@
<li> <a href="#Model-destroy">destroy</a></li>
<li> <a href="#Model-validate">validate</a></li>
<li> <a href="#Model-url">url</a></li>
<li> <a href="#Model-parse">parse</a></li>
<li> <a href="#Model-clone">clone</a></li>
<li> <a href="#Model-isNew">isNew</a></li>
<li> <a href="#Model-change">change</a></li>
@@ -192,6 +203,7 @@
<li> <a href="#Collection-sort">sort</a></li>
<li> <a href="#Collection-pluck">pluck</a></li>
<li> <a href="#Collection-url">url</a></li>
<li> <a href="#Collection-parse">parse</a></li>
<li> <a href="#Collection-fetch">fetch</a></li>
<li> <a href="#Collection-refresh">refresh</a></li>
<li> <a href="#Collection-create">create</a></li>
@@ -212,8 +224,11 @@
<li> <a href="#View-jQuery">$ (jQuery)</a></li>
<li> <a href="#View-render">render</a></li>
<li> <a href="#View-make">make</a></li>
<li> <a href="#View-handleEvents">handleEvents</a></li>
<li> <a href="#View-delegateEvents">delegateEvents</a></li>
</ul>
<a class="toc_title" href="#examples">
Examples
</a>
<a class="toc_title" href="#changelog">
Change Log
</a>
@@ -238,12 +253,12 @@
and the <a href="docs/backbone.html">annotated source code</a> is available,
as well as an online <a href="test/test.html">test suite</a>.
</p>
<p>
You can report bugs and discuss features on the
You can report bugs and discuss features on the
<a href="http://github.com/documentcloud/backbone/issues">issues page</a>,
on Freenode in the <tt>#documentcloud</tt> channel,
or send tweets to <a href="http://twitter.com/documentcloud">@documentcloud</a>.
on Freenode in the <tt>#documentcloud</tt> channel,
or send tweets to <a href="http://twitter.com/documentcloud">@documentcloud</a>.
</p>
<p>
@@ -260,11 +275,11 @@
<table>
<tr>
<td><a href="backbone.js">Development Version (0.1.2)</a></td>
<td><i>23.8kb, Uncompressed with Comments</i></td>
<td><a href="backbone.js">Development Version (0.2.0)</a></td>
<td><i>24.8kb, Uncompressed with Comments</i></td>
</tr>
<tr>
<td><a href="backbone-min.js">Production Version (0.1.2)</a></td>
<td><a href="backbone-min.js">Production Version (0.2.0)</a></td>
<td><i>2.6kb, Packed and Gzipped</i></td>
</tr>
</table>
@@ -459,14 +474,12 @@ var Note = Backbone.Model.extend({
});
</pre>
<p>
<i>
Brief aside on </i><tt>super</tt>: <i>JavaScript does not provide
<p class="warning">
Brief aside on <tt>super</tt>: JavaScript does not provide
a simple way to call super &mdash; the function of the same name defined
higher on the prototype chain. If you override a core function like
</i><tt>set</tt>,<i> or </i><tt>save</tt>, <i>and you want to invoke the
<tt>set</tt>, or <tt>save</tt>, and you want to invoke the
parent object's implementation, you'll have to explicitly call it, along these lines:
</i>
</p>
<pre>
@@ -505,10 +518,12 @@ new Book({
<b class="header">set</b><code>model.set(attributes, [options])</code>
<br />
Set a hash of attributes (one or many) on the model. If any of the attributes
change the models state, a <tt>"change"</tt> event will be fired, unless
<tt>{silent: true}</tt> is passed as an option.
change the models state, a <tt>"change"</tt> event will be triggered, unless
<tt>{silent: true}</tt> is passed as an option. Change events for specific
attributes are also triggered, and you can bind to those as well, for example:
<tt>change:title</tt>, and <tt>change:content</tt>.
</p>
<pre>
note.set({title: "October 12", content: "Lorem Ipsum Dolor Sit Amet..."});
</pre>
@@ -516,9 +531,9 @@ note.set({title: "October 12", content: "Lorem Ipsum Dolor Sit Amet..."});
<p>
If the model has a <a href="#Model-validate">validate</a> method,
it will be validated before the attributes are set, no changes will
occur if the validation fails, and <b>set</b> will return <tt>false</tt>.
You may also pass an <tt>error</tt>
callback in the options, which will be invoked instead of triggering an
occur if the validation fails, and <b>set</b> will return <tt>false</tt>.
You may also pass an <tt>error</tt>
callback in the options, which will be invoked instead of triggering an
<tt>"error"</tt> event, should validation fail.
</p>
@@ -597,13 +612,11 @@ setInterval(function() {
}, 10000);
</pre>
<p>
<i>
<b>Cautionary Note:</b> When fetching or saving a model, make sure that the model is part of
a collection with a <a href="#Collection-url">url</a> property specified,
or that the model itself has a complete <a href="#Model-url">url</a> function
of its own, so that the request knows where to go.
</i>
<p class="warning">
<b>Cautionary Note:</b> When fetching or saving a model, make sure that the model is part of
a collection with a <a href="#Collection-url">url</a> property specified,
or that the model itself has a complete <a href="#Model-url">url</a> function
of its own, so that the request knows where to go.
</p>
<p id="Model-save">
@@ -691,12 +704,12 @@ one.set({
</pre>
<p>
<tt>"error"</tt> events are useful for providing coarse-grained error
<tt>"error"</tt> events are useful for providing coarse-grained error
messages at the model or collection level, but if you have a specific view
that can better handle the error, you may override and suppress the event
that can better handle the error, you may override and suppress the event
by passing an <tt>error</tt> callback directly:
</p>
<pre>
account.set({access: "unlimited"}, {
error: function(model, error) {
@@ -721,6 +734,18 @@ account.set({access: "unlimited"}, {
would have this URL: <tt>"/notes/101"</tt>
</p>
<p id="Model-parse">
<b class="header">parse</b><code>model.parse(response)</code>
<br />
<b>parse</b> is called whenever a model's data is returned by the
server, in <a href="#Model-fetch">fetch</a>, and <a href="#Model-save">save</a>.
The function is passed the raw <tt>response</tt> object, and should return
the attributes hash to be <a href="#Model-set">set</a> on the model. The
default implementation is a no-op, simply passing through the JSON response.
Override this if you need to work with a preexisting API, or better namespace
your responses.
</p>
<p id="Model-clone">
<b class="header">clone</b><code>model.clone()</code>
<br />
@@ -798,13 +823,18 @@ bill.set({name : "Bill Jones"});
<h2 id="Collection">Backbone.Collection</h2>
<p>
Collections are ordered sets of models. You can bind callbacks to be notified
when any model in the collection is changed, listen for <tt>"add"</tt> and
<tt>"remove"</tt> events, <tt>fetch</tt> the collection from the server,
and use a full suite of
Collections are ordered sets of models. You can to bind <tt>"change"</tt> events
to be notified when any model in the collection has been modified,
listen for <tt>"add"</tt> and <tt>"remove"</tt> events, <tt>fetch</tt>
the collection from the server, and use a full suite of
<a href="#Collection-Underscore-Methods">Underscore.js methods</a>.
</p>
<p>
Collections may also listen for changes to specific attributes in their
models, for example: <tt>Documents.bind("change:selected", ...)</tt>
</p>
<p id="Collection-extend">
<b class="header">extend</b><code>Backbone.Collection.extend(properties, [classProperties])</code>
<br />
@@ -850,24 +880,24 @@ var tabs = new TabSet([tab1, tab2, tab3]);
to access model objects, but occasionally a direct reference to the array
is desired.
</p>
<p id="Collection-toJSON">
<b class="header">toJSON</b><code>collection.toJSON()</code>
<br />
Return an array containing the attributes hash of each model in the
collection. This can be used to serialize and persist the
collection. This can be used to serialize and persist the
collection as a whole. The name of this method is a bit confusing, because
it conforms to
it conforms to
<a href="https://developer.mozilla.org/en/JSON#toJSON()_method">JavaScript's JSON API</a>.
</p>
<pre class="runnable">
var collection = new Backbone.Collection([
{name: "Tim", age: 5},
{name: "Ida", age: 26},
{name: "Rob", age: 55}
]);
]);
alert(JSON.stringify(collection));
</pre>
@@ -1020,12 +1050,10 @@ chapters.add(new Chapter({page: 1, title: "The Beginning"}));
alert(chapters.pluck('title'));
</pre>
<p>
<i>
Brief aside: This comparator function is different than JavaScript's regular
"sort", which must return </i><tt>0</tt>, <tt>1</tt>, or <tt>-1</tt>,<i>
and is more similar to a </i><tt>sortBy</tt><i> &mdash; a much nicer API.
</i>
<p class="warning">
Brief aside: This comparator function is different than JavaScript's regular
"sort", which must return <tt>0</tt>, <tt>1</tt>, or <tt>-1</tt>,
and is more similar to a <tt>sortBy</tt> &mdash; a much nicer API.
</p>
<p id="Collection-sort">
@@ -1077,6 +1105,27 @@ var Notes = Backbone.Collection.extend({
return this.document.url() + '/notes';
}
});
</pre>
<p id="Collection-parse">
<b class="header">parse</b><code>collection.parse(response)</code>
<br />
<b>parse</b> is called by Backbone whenever a collection's models are
returned by the server, in <a href="#Collection-fetch">fetch</a>.
The function is passed the raw <tt>response</tt> object, and should return
the array of model attributes to be <a href="#Collection-add">added</a>
to the collection. The default implementation is a no-op, simply passing
through the JSON response. Override this if you need to work with a
preexisting API, or better namespace your responses.
</p>
<pre>
var Tweets = Backbone.Collection.extend({
// The Twitter Search API returns tweets under "results".
parse: function(response) {
return response.results;
}
});
</pre>
<p id="Collection-fetch">
@@ -1090,15 +1139,8 @@ var Notes = Backbone.Collection.extend({
<a href="#Collection-refresh">refresh</a>.
Delegates to <a href="#Sync">Backbone.sync</a>
under the covers, for custom persistence strategies.
</p>
<p>
The server handler for <b>fetch</b> requests should return a JSON list of
models, namespaced under "models": <tt>{"models": [...]}</tt> &mdash;
instead of returning the
array directly, we ask you to namespace your models like this by default,
so that it's possible to send down out-of-band information
for things like pagination or error states.
The server handler for <b>fetch</b> requests should return a JSON array of
models.
</p>
<pre class="runnable">
@@ -1213,7 +1255,7 @@ var othello = NYPL.create({
HTTP <tt>POST</tt>, and passing them under the <tt>_method</tt> parameter
instead, by turning on <tt>Backbone.emulateHttp</tt>:
</p>
<pre>
Backbone.emulateHttp = true;
@@ -1255,7 +1297,7 @@ end
<br />
Get started with views by creating a custom view class. You'll want to
override the <a href="#View-render">render</a> function, specify your
declarative <a href="#View-handleEvents">events</a>, and perhaps the
declarative <a href="#View-delegateEvents">events</a>, and perhaps the
<tt>tagName</tt>, <tt>className</tt>, or <tt>id</tt> of the View's root
element.
</p>
@@ -1403,23 +1445,26 @@ $("#make-demo").append(el);
<div id="make-demo"></div>
<p id="View-handleEvents">
<b class="header">handleEvents</b><code>handleEvents([events])</code>
<p id="View-delegateEvents">
<b class="header">delegateEvents</b><code>delegateEvents([events])</code>
<br />
Uses jQuery's <tt>delegate</tt> function to provide declarative callbacks
for DOM events within a view.
If an <b>events</b> hash is not passed directly, uses <tt>this.events</tt>
as the source. Events are written in the format <tt>{"event selector": "callback"}</tt>.
Omitting the <tt>selector</tt> causes the event to be bound to the view's
root element (<tt>this.el</tt>).
root element (<tt>this.el</tt>). By default, <tt>delegateEvents</tt> is called
within the View's constructor for you, so if you have a simple <tt>events</tt>
hash, all of your DOM events will always already be connected, and you will
never have to call this function yourself.
</p>
<p>
Using <b>handleEvents</b> provides a number of advantages over manually
Using <b>delegateEvents</b> provides a number of advantages over manually
using jQuery to bind events to child elements during <a href="#View-render">render</a>. All attached
callbacks are bound to the view before being handed off to jQuery, so when
the callbacks are invoked, <tt>this</tt> continues to refer to the view object. When
<b>handleEvents</b> is run again, perhaps with a different <tt>events</tt>
<b>delegateEvents</b> is run again, perhaps with a different <tt>events</tt>
hash, all callbacks are removed and delegated afresh &mdash; useful for
views which need to behave differently when in different modes.
</p>
@@ -1443,7 +1488,6 @@ var DocumentView = Backbone.View.extend({
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
this.handleEvents();
return this;
},
@@ -1457,21 +1501,119 @@ var DocumentView = Backbone.View.extend({
...
});
</pre>
<p class="warning">
<b>Cautionary Note:</b> The "delegateEvents" function is
limited to events that work with delegation. "focus" and "blur" do not
bubble, and cannot be delegated, and "change", "submit", and "reset"
events do not bubble in current versions of Internet Explorer.
</p>
<h2 id="examples">Examples</h2>
<p>
As a quick example to help get an idea of how Backbone can be used in a
real-world project, here are the method signatures (beyond the built-in
methods that Backbone provides) of the <b>Document</b>
model, and the <b>DocumentSet</b> collection, as used in
<a href="http://www.documentcloud.org">DocumentCloud</a>. In the workspace,
these classes work together with many others: <b>Project</b>, <b>Note</b>,
<b>Account</b>, <b>Entity</b>, <b>Organization</b>...
</p>
<pre>
dc.model.Document = Backbone.Model.extend({
initialize(attributes): ...
canonicalId: ...
url: ...
viewerUrl: ...
publishedUrl: ...
pageThumbnailURL(page): ...
openViewer: ...
openPublishedViewer: ...
openText: ...
openPDF: ...
allowedToEdit: ...
checkAllowedToEdit(errorMessage): ...
checkBusy: ...
uniquePageEntities: ...
isPending: ...
isPublic: ...
isPublished: ...
toString: ...
});
dc.model.DocumentSet = Backbone.Collection.extend({
model: dc.model.Document,
url: '/documents',
initialize(options): ...
comparator(document): ...
selectAll: ...
deselectAll: ...
selectedIds: ...
filterPending: ...
filterSelected: ...
getCommonAttribute(documents, attribute): ...
allowedToEdit(documents, errorMessage): ...
editAccess(documents): ...
downloadSelectedViewers: ...
downloadSelectedPDFs: ...
downloadSelectedTexts: ...
poll: ...
startPolling: ...
stopPolling: ...
verifyDestroy(documents): ...
});
</pre>
<h2 id="changelog">Change Log</h2>
<p>
<b class="header">0.2.0</b> &mdash; <small><i>Oct 25, 2010</i></small><br />
Instead of requiring server responses to be namespaced under a <tt>model</tt>
key, now you can define your own <a href="#Model-parse">parse</a> method
to convert responses into attributes for Models and Collections.
The old <tt>handleEvents</tt> function is now named
<a href="#View-delegateEvents">delegateEvents</a>, and is automatically
called as part of the View's constructor.
Added a <a href="#Collection-toJSON">toJSON</a> function to Collections.
Added <a href="#Collection-chain">Underscore's chain</a> to Collections.
</p>
<p>
<b class="header">0.1.2</b> &mdash; <small><i>Oct 19, 2010</i></small><br />
Added a <a href="#Model-fetch">Model#fetch</a> method for refreshing the
attributes of single model from the server.
An <tt>error</tt> callback may now be passed to <tt>set</tt> and <tt>save</tt>
as an option, which will be invoked if validation fails, overriding the
as an option, which will be invoked if validation fails, overriding the
<tt>"error"</tt> event.
You can now tell backbone to use the <tt>_method</tt> hack instead of HTTP
methods by setting <tt>Backbone.emulateHttp = true</tt>.
Existing Model and Collection data is no longer sent up unnecessarily with
Existing Model and Collection data is no longer sent up unnecessarily with
<tt>GET</tt> and <tt>DELETE</tt> requests. Added a <tt>rake lint</tt> task.
Backbone is now published as an <a href="http://npmjs.org">NPM</a> module.
</p>

View File

@@ -10,5 +10,5 @@
},
"lib" : ".",
"main" : "backbone.js",
"version" : "0.1.2"
"version" : "0.2.0"
}

View File

@@ -31,6 +31,19 @@ $(document).ready(function() {
equals(col.getByCid(col.first().cid), col.first());
});
test("Collection: update index when id changes", function() {
var col = new Backbone.Collection();
col.add([
{id : 1, name : 'one'},
{id : 2, name : 'two'}
]);
var one = col.get(1);
equals(one.get('name'), 'one');
one.set({id : 101});
equals(col.get(1), null);
equals(col.get(101).get('name'), 'one');
});
test("Collection: at", function() {
equals(col.at(2), b);
});

View File

@@ -37,19 +37,19 @@ $(document).ready(function() {
equals(view.one, 1);
});
test("View: handleEvents", function() {
test("View: delegateEvents", function() {
var counter = 0;
view.el = document.body;
view.increment = function() {
return ++counter;
};
var events = {"click #qunit-banner": "increment"};
view.handleEvents(events);
view.delegateEvents(events);
$('#qunit-banner').trigger('click');
equals(counter, 1);
$('#qunit-banner').trigger('click');
equals(counter, 2);
view.handleEvents(events);
view.delegateEvents(events);
$('#qunit-banner').trigger('click');
equals(counter, 3);
});