mirror of
https://github.com/jashkenas/backbone.git
synced 2026-01-23 13:58:06 -05:00
Issue #8 -- a number of improvements to the documentation.
This commit is contained in:
35
backbone.js
35
backbone.js
@@ -322,17 +322,27 @@
|
||||
// Add a model, or list of models to the set. Pass **silent** to avoid
|
||||
// firing the `added` event for every new model.
|
||||
add : function(models, options) {
|
||||
if (!_.isArray(models)) return this._add(models, options);
|
||||
for (var i=0; i<models.length; i++) this._add(models[i], options);
|
||||
return models;
|
||||
if (_.isArray(models)) {
|
||||
for (var i = 0, l = models.length; i < l; i++) {
|
||||
this._add(models[i], options);
|
||||
}
|
||||
} else {
|
||||
this._add(models, options);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// Remove a model, or a list of models from the set. Pass silent to avoid
|
||||
// firing the `removed` event for every model removed.
|
||||
remove : function(models, options) {
|
||||
if (!_.isArray(models)) return this._remove(models, options);
|
||||
for (var i=0; i<models.length; i++) this._remove(models[i], options);
|
||||
return models;
|
||||
if (_.isArray(models)) {
|
||||
for (var i = 0, l = models.length; i < l; i++) {
|
||||
this._remove(models[i], options);
|
||||
}
|
||||
} else {
|
||||
this._remove(models, options);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
// Get a model from the set by id.
|
||||
@@ -369,14 +379,8 @@
|
||||
// you can refresh the entire set with a new list of models, without firing
|
||||
// any `added` or `removed` events. Fires `refresh` when finished.
|
||||
refresh : function(models, options) {
|
||||
models || (models = []);
|
||||
options || (options = {});
|
||||
models = models || [];
|
||||
var collection = this;
|
||||
if (models[0] && !(models[0] instanceof Backbone.Model)) {
|
||||
models = _.map(models, function(attrs, i) {
|
||||
return new collection.model(attrs);
|
||||
});
|
||||
}
|
||||
this._reset();
|
||||
this.add(models, {silent: true});
|
||||
if (!options.silent) this.trigger('refresh', this);
|
||||
@@ -422,6 +426,9 @@
|
||||
// hash indexes for `id` and `cid` lookups.
|
||||
_add : function(model, options) {
|
||||
options || (options = {});
|
||||
if (!(model instanceof Backbone.Model)) {
|
||||
model = new this.model(model);
|
||||
}
|
||||
var already = this.getByCid(model);
|
||||
if (already) throw new Error(["Can't add the same model to a set twice", already.id]);
|
||||
this._byId[model.id] = model;
|
||||
@@ -432,7 +439,6 @@
|
||||
model.bind('all', this._boundOnModelEvent);
|
||||
this.length++;
|
||||
if (!options.silent) this.trigger('add', model);
|
||||
return model;
|
||||
},
|
||||
|
||||
// Internal implementation of removing a single model from the set, updating
|
||||
@@ -448,7 +454,6 @@
|
||||
model.unbind('all', this._boundOnModelEvent);
|
||||
this.length--;
|
||||
if (!options.silent) this.trigger('remove', model);
|
||||
return model;
|
||||
},
|
||||
|
||||
// Internal method called every time a model in the set fires an event.
|
||||
|
||||
77
index.html
77
index.html
@@ -189,8 +189,8 @@
|
||||
<li>– <a href="#Collection-sort">sort</a></li>
|
||||
<li>– <a href="#Collection-pluck">pluck</a></li>
|
||||
<li>– <a href="#Model-url">url</a></li>
|
||||
<li>– <a href="#Collection-refresh">refresh</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>
|
||||
</ul>
|
||||
<a class="toc_title" href="#Sync">
|
||||
@@ -975,16 +975,6 @@ var Notes = Backbone.Collection.extend({
|
||||
});
|
||||
</pre>
|
||||
|
||||
<p id="Collection-refresh">
|
||||
<b class="header">refresh</b><code>collection.refresh(models, [options])</code>
|
||||
<br />
|
||||
Adding and removing models one at a time is all well and good, but sometimes
|
||||
you have so many models to change that you'd rather just update the collection
|
||||
in bulk. Use <b>refresh</b> to replace a collection with a new list
|
||||
of models (or attribute hashes), triggering a single <tt>"refresh"</tt> event
|
||||
at the end. Pass <tt>{silent: true}</tt> to suppress the <tt>"refresh"</tt> event.
|
||||
</p>
|
||||
|
||||
<p id="Collection-fetch">
|
||||
<b class="header">fetch</b><code>collection.fetch([options])</code>
|
||||
<br />
|
||||
@@ -992,6 +982,8 @@ var Notes = Backbone.Collection.extend({
|
||||
refreshing the collection when they arrive. The <b>options</b> hash takes
|
||||
<tt>success</tt> and <tt>error</tt>
|
||||
callbacks which will be passed <tt>(collection, response)</tt> as arguments.
|
||||
When the model data returns from the server, the collection will
|
||||
<a href="#Collection-refresh">refresh</a>.
|
||||
Delegates to <a href="#Sync">Backbone.sync</a>
|
||||
under the covers, for custom persistence strategies.
|
||||
</p>
|
||||
@@ -1007,10 +999,10 @@ Backbone.sync = function(method, model) {
|
||||
alert(method + ": " + model.url);
|
||||
};
|
||||
|
||||
var accounts = new Backbone.Collection;
|
||||
accounts.url = '/accounts';
|
||||
var Accounts = new Backbone.Collection;
|
||||
Accounts.url = '/accounts';
|
||||
|
||||
accounts.fetch();
|
||||
Accounts.fetch();
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -1020,6 +1012,27 @@ accounts.fetch();
|
||||
for interfaces that are not needed immediately: for example, documents
|
||||
with collections of notes that may be toggled open and closed.
|
||||
</p>
|
||||
|
||||
<p id="Collection-refresh">
|
||||
<b class="header">refresh</b><code>collection.refresh(models, [options])</code>
|
||||
<br />
|
||||
Adding and removing models one at a time is all well and good, but sometimes
|
||||
you have so many models to change that you'd rather just update the collection
|
||||
in bulk. Use <b>refresh</b> to replace a collection with a new list
|
||||
of models (or attribute hashes), triggering a single <tt>"refresh"</tt> event
|
||||
at the end. Pass <tt>{silent: true}</tt> to suppress the <tt>"refresh"</tt> event.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Here's an example using <b>refresh</b> to bootstrap a collection during initial page load,
|
||||
in a Rails application.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<script>
|
||||
Accounts.refresh(<%= @accounts.to_json %>);
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
<p id="Collection-create">
|
||||
<b class="header">create</b><code>collection.create(attributes, [options])</code>
|
||||
@@ -1150,7 +1163,9 @@ var DocumentRow = Backbone.View.extend({
|
||||
<tt>model</tt>, <tt>collection</tt>,
|
||||
<tt>el</tt>, <tt>id</tt>, <tt>className</tt>, and <tt>tagName</tt>.
|
||||
If the view defines an <b>initialize</b> function, it will be called when
|
||||
the view is first created.
|
||||
the view is first created. If you'd like to create a view that references
|
||||
an element already in the DOM, pass in the element as an option:
|
||||
<tt>new View({el: existingElement})</tt>
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -1204,11 +1219,7 @@ ui.Chapter = Backbone.View.extend({
|
||||
<br />
|
||||
The default implementation of <b>render</b> is a no-op. Override this
|
||||
function with your code that renders the view template from model data,
|
||||
and updates <tt>this.el</tt> with the new HTML. You can use any flavor of
|
||||
JavaScript templating or DOM-building you prefer. Because <b>Underscore.js</b>
|
||||
is already on the page,
|
||||
<a href="http://documentcloud.github.com/underscore/#template">_.template</a>
|
||||
is already available. A good
|
||||
and updates <tt>this.el</tt> with the new HTML. A good
|
||||
convention is to <tt>return this</tt> at the end of <b>render</b> to
|
||||
enable chained calls.
|
||||
</p>
|
||||
@@ -1216,12 +1227,34 @@ ui.Chapter = Backbone.View.extend({
|
||||
<pre>
|
||||
var Bookmark = Backbone.View.extend({
|
||||
render: function() {
|
||||
$(this.el).html(this.template.render(this.model.toJSON()));
|
||||
$(this.el).html(this.template(this.model.toJSON()));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Backbone is agnostic with respect to your preferred method of HTML templating.
|
||||
Your <b>render</b> function could even munge together an HTML string, or use
|
||||
<tt>document.createElement</tt> to generate a DOM tree. However, we suggest
|
||||
choosing a nice JavaScript templating library.
|
||||
<a href="http://github.com/janl/mustache.js">Mustache.js</a>,
|
||||
<a href="http://github.com/creationix/haml-js">Haml-js</a>, and
|
||||
<a href="http://github.com/sstephenson/eco">Eco</a> are all fine alternatives.
|
||||
Because <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> is already on the page,
|
||||
<a href="http://documentcloud.github.com/underscore/#template">_.template</a>
|
||||
is available, and is an excellent choice if you've already XSS-sanitized
|
||||
your interpolated data.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Whatever templating strategy you end up with, it's nice if you <i>never</i>
|
||||
have to put strings of HTML in your JavaScript. At DocumentCloud, we
|
||||
use <a href="http://documentcloud.github.com/jammit/">Jammit</a> in order
|
||||
to package up JavaScript templates stored in <tt>/app/views</tt> as part
|
||||
of our main <tt>core.js</tt> asset package.
|
||||
</p>
|
||||
|
||||
<p id="View-make">
|
||||
<b class="header">make</b><code>view.make(tagName, [attributes], [content])</code>
|
||||
<br />
|
||||
@@ -1279,7 +1312,7 @@ var DocumentView = Backbone.View.extend({
|
||||
},
|
||||
|
||||
render: function() {
|
||||
$(this.el).html(this.template.render(this.model.toJSON()));
|
||||
$(this.el).html(this.template(this.model.toJSON()));
|
||||
this.handleEvents();
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -58,20 +58,6 @@ $(document).ready(function() {
|
||||
equals(col.first(), d);
|
||||
});
|
||||
|
||||
test("collections: refresh", function() {
|
||||
var refreshed = 0;
|
||||
var models = col.models;
|
||||
col.bind('refresh', function() { refreshed += 1; });
|
||||
col.refresh([]);
|
||||
equals(refreshed, 1);
|
||||
equals(col.length, 0);
|
||||
equals(col.last(), null);
|
||||
col.refresh(models);
|
||||
equals(refreshed, 2);
|
||||
equals(col.length, 4);
|
||||
equals(col.last(), a);
|
||||
});
|
||||
|
||||
test("collections: fetch", function() {
|
||||
col.fetch();
|
||||
equals(lastRequest[0], 'read');
|
||||
@@ -111,4 +97,23 @@ $(document).ready(function() {
|
||||
equals(col.min(function(model){ return model.id; }).id, 1);
|
||||
});
|
||||
|
||||
test("collections: refresh", function() {
|
||||
var refreshed = 0;
|
||||
var models = col.models;
|
||||
col.bind('refresh', function() { refreshed += 1; });
|
||||
col.refresh([]);
|
||||
equals(refreshed, 1);
|
||||
equals(col.length, 0);
|
||||
equals(col.last(), null);
|
||||
col.refresh(models);
|
||||
equals(refreshed, 2);
|
||||
equals(col.length, 4);
|
||||
equals(col.last(), a);
|
||||
col.refresh(_.map(models, function(m){ return m.attributes; }));
|
||||
equals(refreshed, 3);
|
||||
equals(col.length, 4);
|
||||
ok(col.last() !== a);
|
||||
ok(_.isEqual(col.last().attributes, a.attributes));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user