mirror of
https://github.com/jashkenas/backbone.git
synced 2026-04-08 03:00:26 -04:00
attributes is now a public property, uncloned. documenting comparator, and more.
This commit is contained in:
32
backbone.js
32
backbone.js
@@ -112,15 +112,10 @@
|
||||
// Create a new model, with defined attributes.
|
||||
// If you do not specify the id, a negative id will be assigned for you.
|
||||
Backbone.Model = function(attributes) {
|
||||
this._attributes = {};
|
||||
this.attributes = {};
|
||||
this.cid = _.uniqueId('c');
|
||||
this.set(attributes || {}, {silent : true});
|
||||
this._previousAttributes = this.attributes();
|
||||
};
|
||||
|
||||
// `attributes` is aliased as `toJSON`, for use with `JSON.stringify`.
|
||||
var toJSON = function() {
|
||||
return _.clone(this._attributes);
|
||||
this._previousAttributes = _.clone(this.attributes);
|
||||
};
|
||||
|
||||
// Attach all inheritable methods to the Model prototype.
|
||||
@@ -134,12 +129,13 @@
|
||||
_changed : false,
|
||||
|
||||
// Return a copy of the model's `attributes` object.
|
||||
toJSON : toJSON,
|
||||
attributes : toJSON,
|
||||
toJSON : function() {
|
||||
return _.clone(this.attributes);
|
||||
},
|
||||
|
||||
// Get the value of an attribute.
|
||||
get : function(attr) {
|
||||
return this._attributes[attr];
|
||||
return this.attributes[attr];
|
||||
},
|
||||
|
||||
// Set a hash of model attributes on the object, firing `changed` unless you
|
||||
@@ -149,8 +145,8 @@
|
||||
// Extract attributes and options.
|
||||
options || (options = {});
|
||||
if (!attrs) return this;
|
||||
attrs = attrs._attributes || attrs;
|
||||
var now = this._attributes;
|
||||
attrs = attrs.attributes || attrs;
|
||||
var now = this.attributes;
|
||||
|
||||
// Run validation if `validate` is defined.
|
||||
if (this.validate) {
|
||||
@@ -186,8 +182,8 @@
|
||||
// silence it.
|
||||
unset : function(attr, options) {
|
||||
options || (options = {});
|
||||
var value = this._attributes[attr];
|
||||
delete this._attributes[attr];
|
||||
var value = this.attributes[attr];
|
||||
delete this.attributes[attr];
|
||||
if (!options.silent) {
|
||||
this._changed = true;
|
||||
this.trigger('change:' + attr, this);
|
||||
@@ -234,7 +230,7 @@
|
||||
|
||||
// Create a new model with identical attributes to this one.
|
||||
clone : function() {
|
||||
return new (this.constructor)(this.attributes());
|
||||
return new this.constructor(this);
|
||||
},
|
||||
|
||||
// A model is new if it has never been saved to the server, and has a negative
|
||||
@@ -247,14 +243,14 @@
|
||||
// Calling this will cause all objects observing the model to update.
|
||||
change : function() {
|
||||
this.trigger('change', this);
|
||||
this._previousAttributes = this.attributes();
|
||||
this._previousAttributes = _.clone(this.attributes);
|
||||
this._changed = false;
|
||||
},
|
||||
|
||||
// Determine if the model has changed since the last `changed` event.
|
||||
// If you specify an attribute name, determine if that attribute has changed.
|
||||
hasChanged : function(attr) {
|
||||
if (attr) return this._previousAttributes[attr] != this._attributes[attr];
|
||||
if (attr) return this._previousAttributes[attr] != this.attributes[attr];
|
||||
return this._changed;
|
||||
},
|
||||
|
||||
@@ -263,7 +259,7 @@
|
||||
// view need to be updated and/or what attributes need to be persisted to
|
||||
// the server.
|
||||
changedAttributes : function(now) {
|
||||
var old = this._previousAttributes, now = now || this.attributes(), changed = false;
|
||||
var old = this._previousAttributes, now = now || this.attributes, changed = false;
|
||||
for (var attr in now) {
|
||||
if (!_.isEqual(old[attr], now[attr])) {
|
||||
changed = changed || {};
|
||||
|
||||
88
index.html
88
index.html
@@ -153,6 +153,7 @@
|
||||
<li>– <a href="#Model-id">id</a></li>
|
||||
<li>– <a href="#Model-cid">cid</a></li>
|
||||
<li>– <a href="#Model-attributes">attributes</a></li>
|
||||
<li>- <a href="#Model-toJSON">toJSON</a></li>
|
||||
<li>– <a href="#Model-save">save</a></li>
|
||||
<li>– <a href="#Model-destroy">destroy</a></li>
|
||||
<li>– <a href="#Model-validate">validate</a></li>
|
||||
@@ -171,12 +172,14 @@
|
||||
</a>
|
||||
<ul class="toc_section">
|
||||
<li>– <a href="#Collection-extend">extend</a></li>
|
||||
<li>– <a href="#Collection-models">models</a></li>
|
||||
<li>– <a href="#Collection-Underscore-Methods"><b>Underscore Methods (24)</b></a></li>
|
||||
<li>– <a href="#Collection-add">add</a></li>
|
||||
<li>– <a href="#Collection-remove">remove</a></li>
|
||||
<li>– <a href="#Collection-get">get</a></li>
|
||||
<li>– <a href="#Collection-getByCid">getByCid</a></li>
|
||||
<li>– <a href="#Collection-at">at</a></li>
|
||||
<li>– <a href="#Collection-comparator">comparator</a></li>
|
||||
<li>– <a href="#Collection-sort">sort</a></li>
|
||||
<li>– <a href="#Collection-pluck">pluck</a></li>
|
||||
<li>– <a href="#Model-url">url</a></li>
|
||||
@@ -201,6 +204,9 @@
|
||||
<li>– <a href="#View-make">make</a></li>
|
||||
<li>– <a href="#View-handleEvents">handleEvents</a></li>
|
||||
</ul>
|
||||
<a class="toc_title" href="#changelog">
|
||||
Change Log
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
@@ -492,10 +498,20 @@ note.set({title: "October 31"}, {silent: true});
|
||||
</p>
|
||||
|
||||
<p id="Model-attributes">
|
||||
<b class="header">attributes</b><code>model.attributes()</code>
|
||||
<b class="header">attributes</b><code>model.attributes</code>
|
||||
<br />
|
||||
Return a copy of the model's <b>attributes</b>. This can be used for persistence,
|
||||
serialization, or for augmentation before being handed off to a view.
|
||||
The <b>attributes</b> property is the internal hash containing the model's
|
||||
state. Please use <tt>set</tt> to update the attributes instead of modifying
|
||||
them directly. If you'd like to retrieve and munge a copy of the model's
|
||||
attributes, use <tt>toJSON</tt> instead.
|
||||
</p>
|
||||
|
||||
<p id="Model-toJSON">
|
||||
<b class="header">toJSON</b><code>model.toJSON</code>
|
||||
<br />
|
||||
Return a copy of the model's <b>attributes</b> for JSON stringification.
|
||||
This can be used for persistence, serialization, or for augmentation before
|
||||
being handed off to a view.
|
||||
</p>
|
||||
|
||||
<pre class="runnable">
|
||||
@@ -506,7 +522,7 @@ var artist = new Backbone.Model({
|
||||
|
||||
artist.set({birthday: "December 16, 1866"});
|
||||
|
||||
alert(JSON.stringify(artist.attributes()));
|
||||
alert(JSON.stringify(artist));
|
||||
</pre>
|
||||
|
||||
<p id="Model-save">
|
||||
@@ -519,6 +535,11 @@ alert(JSON.stringify(artist.attributes()));
|
||||
exists on the server, the save will be a <tt>PUT</tt>. Accepts
|
||||
<tt>success</tt> and <tt>error</tt> callbacks in the options hash.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In the following example, notice how because the model has never been
|
||||
saved previously, <tt>Backbone.sync</tt> receives a <tt>"create"</tt> request.
|
||||
</p>
|
||||
|
||||
<pre class="runnable">
|
||||
Backbone.sync = function(method, model) {
|
||||
@@ -542,11 +563,9 @@ book.save();
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
book.destroy({
|
||||
success: function(model, response) {
|
||||
...
|
||||
}
|
||||
});
|
||||
book.destroy({success: function(model, response) {
|
||||
...
|
||||
}});
|
||||
</pre>
|
||||
|
||||
<p id="Model-validate">
|
||||
@@ -699,6 +718,15 @@ bill.set({name : "Bill Jones"});
|
||||
providing instance <b>properties</b>, as well as optional properties to be attached
|
||||
directly to the collection constructor function.
|
||||
</p>
|
||||
|
||||
<p id="Collection-models">
|
||||
<b class="header">models</b><code>collection.models</code>
|
||||
<br />
|
||||
Raw access to the JavaScript array of models inside of the collection. Usually you'll
|
||||
want to use <tt>get</tt>, <tt>at</tt>, or the <b>Underscore methods</b>
|
||||
to access model objects, but occasionally a direct reference to the array
|
||||
is desired.
|
||||
</p>
|
||||
|
||||
<p id="Collection-Underscore-Methods">
|
||||
<b class="header">Underscore Methods (24)</b>
|
||||
@@ -761,14 +789,13 @@ var alphabetical = Books.sortBy(function(book) {
|
||||
</p>
|
||||
|
||||
<pre class="runnable">
|
||||
var Ship = Backbone.Model;
|
||||
var ships = new Backbone.Collection();
|
||||
|
||||
ships.bind("add", function(ship) {
|
||||
alert("Ahoy " + ship.get("name") + "!");
|
||||
});
|
||||
|
||||
var Ship = Backbone.Model.extend({});
|
||||
|
||||
ships.add([
|
||||
new Ship({name: "Flying Dutchman"}),
|
||||
new Ship({name: "Black Pearl"})
|
||||
@@ -805,6 +832,37 @@ ships.add([
|
||||
is sorted, and if your collection isn't sorted, <b>at</b> will still
|
||||
retrieve models in insertion order.
|
||||
</p>
|
||||
|
||||
<p id="Collection-comparator">
|
||||
<b class="header">comparator</b><code>collection.comparator</code>
|
||||
<br />
|
||||
By default there is no <b>comparator</b> function on a collection.
|
||||
If you define a comparator function, it will be used to always maintain
|
||||
the collection in sorted order. This means that as models are added,
|
||||
they are inserted at the correct index in <tt>collection.models</tt>.
|
||||
Comparator functions take a model and return a numeric or string value
|
||||
by which the model should be ordered relative to others.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note how all of the chapters in this example come out in the
|
||||
proper order:
|
||||
</p>
|
||||
|
||||
<pre class="runnable">
|
||||
var Chapter = Backbone.Model;
|
||||
var chapters = new Backbone.Collection();
|
||||
|
||||
chapters.comparator = function(chapter) {
|
||||
return chapter.get("page");
|
||||
};
|
||||
|
||||
chapters.add(new Chapter({page: 9, title: "The End"}));
|
||||
chapters.add(new Chapter({page: 5, title: "The Middle"}));
|
||||
chapters.add(new Chapter({page: 1, title: "The Beginning"}));
|
||||
|
||||
alert(chapters.pluck('title'));
|
||||
</pre>
|
||||
|
||||
<p id="Collection-sort">
|
||||
<b class="header">sort</b><code>collection.sort([options])</code>
|
||||
@@ -991,8 +1049,7 @@ ui.Chapter = Backbone.View.extend({
|
||||
<pre>
|
||||
ui.Chapter = Backbone.View.extend({
|
||||
render: function() {
|
||||
var data = this.model.attributes();
|
||||
$(this.el).html(this.template.render(data));
|
||||
$(this.el).html(this.template.render(this.model.toJSON()));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
@@ -1043,8 +1100,7 @@ var DocumentView = Backbone.View.extend({
|
||||
},
|
||||
|
||||
render: {
|
||||
var data = this.document.attributes();
|
||||
this.el.html(this.template.render(data));
|
||||
$(this.el).html(this.template.render(this.model.toJSON()));
|
||||
this.handleEvents();
|
||||
return this;
|
||||
}
|
||||
@@ -1057,7 +1113,7 @@ var DocumentView = Backbone.View.extend({
|
||||
|
||||
|
||||
|
||||
<h2 id="changes">Change Log</h2>
|
||||
<h2 id="changelog">Change Log</h2>
|
||||
|
||||
<p>
|
||||
<b class="header">0.1.0</b><br />
|
||||
|
||||
@@ -26,11 +26,6 @@ $(document).ready(function() {
|
||||
var collection = new klass();
|
||||
collection.add(doc);
|
||||
|
||||
test("model: attributes", function() {
|
||||
ok(doc.attributes() !== attrs, "Attributes are different objects.");
|
||||
ok(_.isEqual(doc.attributes(), attrs), "but with identical contents.");
|
||||
});
|
||||
|
||||
test("model: url", function() {
|
||||
equals(doc.url(), '/collection/1-the-tempest');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user