diff --git a/backbone/LICENSE b/backbone/LICENSE deleted file mode 100644 index d8cef48..0000000 --- a/backbone/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2010 Jeremy Ashkenas, DocumentCloud - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/backbone/README b/backbone/README deleted file mode 100644 index 0723e1a..0000000 --- a/backbone/README +++ /dev/null @@ -1,25 +0,0 @@ - ____ _ _ _ - | _ \ | | | | (_) - | |_) | __ _ ___| | __| |__ ___ _ __ ___ _ ___ - | _ < / _` |/ __| |/ /| '_ \ / _ \| '_ \ / _ \ | / __| - | |_) | (_| | (__| < | |_) | (_) | | | | __/_| \__ \ - |____/ \__,_|\___|_|\_\|_.__/ \___/|_| |_|\___(_) |___/ - _/ | - |__/ -(_'___________________________________________________'_) -(_.———————————————————————————————————————————————————._) - - -Backbone supplies structure to JavaScript-heavy applications by providing models key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface. - -For Docs, License, Tests, and pre-packed downloads, see: -http://documentcloud.github.com/backbone/ - -To suggest a feature, report a bug, or general discussion: -http://github.com/documentcloud/backbone/issues/ - -All contributors are listed here: -http://github.com/documentcloud/backbone/contributors - -Special thanks to Robert Kieffer for the original philosophy behind Backbone. -http://github.com/broofa diff --git a/backbone/Rakefile b/backbone/Rakefile deleted file mode 100644 index f0b0cf6..0000000 --- a/backbone/Rakefile +++ /dev/null @@ -1,42 +0,0 @@ -require 'rubygems' - -HEADER = /((^\s*\/\/.*\n)+)/ - -desc "rebuild the backbone-min.js files for distribution" -task :build do - begin - require 'closure-compiler' - rescue LoadError - puts "closure-compiler not found.\nInstall it by running 'gem install closure-compiler" - exit - end - source = File.read 'backbone.js' - header = source.match(HEADER) - File.open('backbone-min.js', 'w+') do |file| - file.write header[1].squeeze(' ') + Closure::Compiler.new.compress(source) - end -end - -desc "build the docco documentation" -task :doc do - check 'docco', 'docco', 'https://github.com/jashkenas/docco' - system 'docco backbone.js && docco examples/todos/todos.js examples/backbone-localstorage.js' -end - -desc "run JavaScriptLint on the source" -task :lint do - system "jsl -nofilelisting -nologo -conf docs/jsl.conf -process backbone.js" -end - -desc "test the CoffeeScript integration" -task :test do - check 'coffee', 'CoffeeScript', 'https://github.com/jashkenas/coffee-script.git' - system "coffee test/*.coffee" -end - -# Check for the existence of an executable. -def check(exec, name, url) - return unless `which #{exec}`.empty? - puts "#{name} not found.\nInstall it from #{url}" - exit -end diff --git a/backbone/examples/backbone-localstorage.js b/backbone/examples/backbone-localstorage.js deleted file mode 100644 index 091d7f3..0000000 --- a/backbone/examples/backbone-localstorage.js +++ /dev/null @@ -1,84 +0,0 @@ -// A simple module to replace `Backbone.sync` with *localStorage*-based -// persistence. Models are given GUIDS, and saved into a JSON object. Simple -// as that. - -// Generate four random hex digits. -function S4() { - return (((1+Math.random())*0x10000)|0).toString(16).substring(1); -}; - -// Generate a pseudo-GUID by concatenating random hexadecimal. -function guid() { - return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()); -}; - -// Our Store is represented by a single JS object in *localStorage*. Create it -// with a meaningful name, like the name you'd give a table. -var Store = function(name) { - this.name = name; - var store = localStorage.getItem(this.name); - this.data = (store && JSON.parse(store)) || {}; -}; - -_.extend(Store.prototype, { - - // Save the current state of the **Store** to *localStorage*. - save: function() { - localStorage.setItem(this.name, JSON.stringify(this.data)); - }, - - // Add a model, giving it a (hopefully)-unique GUID, if it doesn't already - // have an id of it's own. - create: function(model) { - if (!model.id) model.id = model.attributes.id = guid(); - this.data[model.id] = model; - this.save(); - return model; - }, - - // Update a model by replacing its copy in `this.data`. - update: function(model) { - this.data[model.id] = model; - this.save(); - return model; - }, - - // Retrieve a model from `this.data` by id. - find: function(model) { - return this.data[model.id]; - }, - - // Return the array of all models currently in storage. - findAll: function() { - return _.values(this.data); - }, - - // Delete a model from `this.data`, returning it. - destroy: function(model) { - delete this.data[model.id]; - this.save(); - return model; - } - -}); - -// Override `Backbone.sync` to use delegate to the model or collection's -// *localStorage* property, which should be an instance of `Store`. -Backbone.sync = function(method, model, options) { - - var resp; - var store = model.localStorage || model.collection.localStorage; - - switch (method) { - case "read": resp = model.id ? store.find(model) : store.findAll(); break; - case "create": resp = store.create(model); break; - case "update": resp = store.update(model); break; - case "delete": resp = store.destroy(model); break; - } - - if (resp) { - options.success(resp); - } else { - options.error("Record not found"); - } -}; \ No newline at end of file diff --git a/backbone/examples/todos/destroy.png b/backbone/examples/todos/destroy.png deleted file mode 100644 index 56d7637..0000000 Binary files a/backbone/examples/todos/destroy.png and /dev/null differ diff --git a/backbone/examples/todos/index.html b/backbone/examples/todos/index.html deleted file mode 100644 index 7f1c20f..0000000 --- a/backbone/examples/todos/index.html +++ /dev/null @@ -1,87 +0,0 @@ - - - -
-
-
-
- Backbone - supplies structure to JavaScript-heavy applications by providing models with - key-value binding and custom events, collections with a rich API of enumerable functions, - views with declarative event handling, and connects it all to your - existing application over a RESTful JSON interface. -
- -- The project is hosted on GitHub, - and the annotated source code is available, - as well as an online test suite, an - example application and a - list of tutorials. -
- -- You can report bugs and discuss features on the - GitHub issues page, - on Freenode IRC in the #documentcloud channel, post questions to the - Google Group, - or send tweets to @documentcloud. -
- -- - Backbone is an open-source component of - DocumentCloud. - -
- -Development Version (0.5.1) | -41kb, Full Source with Comments | -
Production Version (0.5.1) | -4.6kb, Packed and Gzipped | -
- Backbone's only hard dependency is - Underscore.js. - For RESTful persistence, history support via Backbone.Router - and DOM manipulation with Backbone.View, include - json2.js, and either - jQuery ( > 1.4.2) or - Zepto. -
- -- We've taken the opportunity to clarify some naming with the 0.5.0 - release. Controller is now Router, and - refresh is now reset. - The previous saveLocation and setLocation - functions have been replaced by navigate. - Backbone.sync's method signature has changed to allow the passing - of arbitrary options to jQuery.ajax. - Be sure to opt-in to pushState support, - if you want to use it. -
- -- When working on a web application that involves a lot of JavaScript, one - of the first things you learn is to stop tying your data to the DOM. It's all - too easy to create JavaScript applications that end up as tangled piles of - jQuery selectors and callbacks, all trying frantically to keep data in - sync between the HTML UI, your JavaScript logic, and the database on your - server. For rich client-side applications, a more structured approach - is often helpful. -
- -- With Backbone, you represent your data as - Models, which can be created, validated, destroyed, - and saved to the server. Whenever a UI action causes an attribute of - a model to change, the model triggers a "change" event; all - the Views that display the model's data are notified of the - event, causing them to re-render. You don't have to write the glue - code that looks into the DOM to find an element with a specific id, - and update the HTML manually - — when the model changes, the views simply update themselves. -
- -- Many of the examples that follow are runnable. Click the play button - to execute them. -
- -- Events is a module that can be mixed in to any object, giving the - object the ability to bind and trigger custom named events. Events do not - have to be declared before they are bound, and may take passed arguments. - For example: -
- --var object = {}; - -_.extend(object, Backbone.Events); - -object.bind("alert", function(msg) { - alert("Triggered " + msg); -}); - -object.trigger("alert", "an event"); -- -
- bindobject.bind(event, callback)
-
- Bind a callback function to an object. The callback will be invoked
- whenever the event (specified by an arbitrary string identifier) is fired.
- If you have a large number of different events on a page, the convention is to use colons to
- namespace them: "poll:start", or "change:selection"
-
- Callbacks bound to the special - "all" event will be triggered when any event occurs, and are passed - the name of the event as the first argument. For example, to proxy all events - from one object to another: -
- --proxy.bind("all", function(eventName) { - object.trigger(eventName); -}); -- -
- unbindobject.unbind([event], [callback])
-
- Remove a previously-bound callback function from an object. If no
- callback is specified, all callbacks for the event will be
- removed. If no event is specified, all event callbacks on the object
- will be removed.
-
-object.unbind("change", onChange); // Removes just the onChange callback. - -object.unbind("change"); // Removes all "change" callbacks. - -object.unbind(); // Removes all callbacks on object. -- -
- triggerobject.trigger(event, [*args])
-
- Trigger callbacks for the given event. Subsequent arguments to
- trigger will be passed along to the event callbacks.
-
- Models are the heart of any JavaScript application, containing - the interactive data as well as a large part of the logic surrounding it: - conversions, validations, computed properties, and access control. You - extend Backbone.Model with your domain-specific methods, and - Model provides a basic set of functionality for managing changes. -
- -- The following is a contrived example, but it demonstrates defining a model - with a custom method, setting an attribute, and firing an event keyed - to changes in that specific attribute. - After running this code once, sidebar will be - available in your browser's console, so you can play around with it. -
- --var Sidebar = Backbone.Model.extend({ - promptColor: function() { - var cssColor = prompt("Please enter a CSS color:"); - this.set({color: cssColor}); - } -}); - -window.sidebar = new Sidebar; - -sidebar.bind('change:color', function(model, color) { - $('#sidebar').css({background: color}); -}); - -sidebar.set({color: 'white'}); - -sidebar.promptColor(); -- -
- extendBackbone.Model.extend(properties, [classProperties])
-
- To create a Model class of your own, you extend Backbone.Model
- and provide instance properties, as well as optional
- classProperties to be attached directly to the constructor function.
-
- extend correctly sets up the prototype chain, so subclasses created - with extend can be further extended and subclassed as far as you like. -
- --var Note = Backbone.Model.extend({ - - initialize: function() { ... }, - - author: function() { ... }, - - coordinates: function() { ... }, - - allowedToEdit: function(account) { - return true; - } - -}); - -var PrivateNote = Note.extend({ - - allowedToEdit: function(account) { - return account.owns(this); - } - -}); -- -
- Brief aside on super: JavaScript does not provide - a simple way to call super — the function of the same name defined - higher on the prototype chain. If you override a core function like - set, or save, and you want to invoke the - parent object's implementation, you'll have to explicitly call it, along these lines: -
- --var Note = Backbone.Model.extend({ - set: function(attributes, options) { - Backbone.Model.prototype.set.call(this, attributes, options); - ... - } -}); -- -
- constructor / initializenew Model([attributes])
-
- When creating an instance of a model, you can pass in the initial values
- of the attributes, which will be set on the
- model. If you define an initialize function, it will be invoked when
- the model is created.
-
-new Book({ - title: "One Thousand and One Nights", - author: "Scheherazade" -}); -- -
- getmodel.get(attribute)
-
- Get the current value of an attribute from the model. For example:
- note.get("title")
-
- setmodel.set(attributes, [options])
-
- Set a hash of attributes (one or many) on the model. If any of the attributes
- change the models state, a "change" event will be triggered, unless
- {silent: true} is passed as an option. Change events for specific
- attributes are also triggered, and you can bind to those as well, for example:
- change:title, and change:content.
-
-note.set({title: "October 12", content: "Lorem Ipsum Dolor Sit Amet..."}); -- -
- If the model has a validate method, - it will be validated before the attributes are set, no changes will - occur if the validation fails, and set will return false. - You may also pass an error - callback in the options, which will be invoked instead of triggering an - "error" event, should validation fail. -
- -
- escapemodel.escape(attribute)
-
- Similar to get, but returns the HTML-escaped version
- of a model's attribute. If you're interpolating data from the model into
- HTML, using escape to retrieve attributes will prevent
- XSS attacks.
-
-var hacker = new Backbone.Model({ - name: "<script>alert('xss')</script>" -}); - -alert(hacker.escape('name')); -- -
- hasmodel.has(attribute)
-
- Returns true if the attribute is set to a non-null or non-undefined
- value.
-
-if (note.has("title")) { - ... -} -- -
- unsetmodel.unset(attribute, [options])
-
- Remove an attribute by deleting it from the internal attributes hash.
- Fires a "change" event unless silent is passed as an option.
-
- clearmodel.clear([options])
-
- Removes all attributes from the model. Fires a "change" event unless
- silent is passed as an option.
-
- idmodel.id
-
- A special property of models, the id is an arbitrary string
- (integer id or UUID). If you set the id in the
- attributes hash, it will be copied onto the model as a direct property.
- Models can be retrieved by id from collections, and the id is used to generate
- model URLs by default.
-
- cidmodel.cid
-
- A special property of models, the cid or client id is a unique identifier
- automatically assigned to all models when they're first created. Client ids
- are handy when the model has not yet been saved to the server, and does not
- yet have its eventual true id, but already needs to be visible in the UI.
- Client ids take the form: c1, c2, c3 ...
-
- attributesmodel.attributes
-
- The attributes property is the internal hash containing the model's
- state. Please use set 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 toJSON instead.
-
- defaultsmodel.defaults or model.defaults()
-
- The defaults hash (or function) can be used to specify the default
- attributes for your model. When creating an instance of the model,
- any unspecified attributes will be set to their default value.
-
-var Meal = Backbone.Model.extend({ - defaults: { - "appetizer": "caesar salad", - "entree": "ravioli", - "dessert": "cheesecake" - } -}); - -alert("Dessert will be " + (new Meal).get('dessert')); -- -
- Remember that in JavaScript, objects are passed by reference, so if you - include an object as a default value, it will be shared among all instances. -
- -
- toJSONmodel.toJSON()
-
- Return a copy of the model's attributes for JSON stringification.
- This can be used for persistence, serialization, or for augmentation before
- being handed off to a view. The name of this method is a bit confusing, as
- it doesn't actually return a JSON string — but I'm afraid that it's
- the way that the JavaScript API for JSON.stringify works.
-
-var artist = new Backbone.Model({ - firstName: "Wassily", - lastName: "Kandinsky" -}); - -artist.set({birthday: "December 16, 1866"}); - -alert(JSON.stringify(artist)); -- -
- fetchmodel.fetch([options])
-
- Resets the model's state from the server. Useful if the model has never
- been populated with data, or if you'd like to ensure that you have the
- latest server state. A "change" event will be triggered if the
- server's state differs from the current attributes. Accepts
- success and error callbacks in the options hash, which
- are passed (model, response) as arguments.
-
-// Poll every 10 seconds to keep the channel model up-to-date. -setInterval(function() { - channel.fetch(); -}, 10000); -- -
- savemodel.save([attributes], [options])
-
- Save a model to your database (or alternative persistence layer),
- by delegating to Backbone.sync. The attributes
- hash (as in set) should contain the attributes
- you'd like to change -- keys that aren't mentioned won't be altered.
- If the model has a validate
- method, and validation fails, the model will not be saved. If the model
- isNew, the save will be a "create"
- (HTTP POST), if the model already
- exists on the server, the save will be an "update" (HTTP PUT).
-
- In the following example, notice how our overridden version - of Backbone.sync receives a "create" request - the first time the model is saved and an "update" - request the second time. -
- --Backbone.sync = function(method, model) { - alert(method + ": " + JSON.stringify(model)); - model.id = 1; -}; - -var book = new Backbone.Model({ - title: "The Rough Riders", - author: "Theodore Roosevelt" -}); - -book.save(); - -book.save({author: "Teddy"}); -- -
- save accepts success and error callbacks in the - options hash, which are passed (model, response) as arguments. - The error callback will also be invoked if the model has a - validate method, and validation fails. If a server-side - validation fails, return a non-200 HTTP response code, along with - an error response in text or JSON. -
- --book.save({author: "F.D.R."}, {error: function(){ ... }}); -- -
- destroymodel.destroy([options])
-
- Destroys the model on the server by delegating an HTTP DELETE
- request to Backbone.sync. Accepts
- success and error callbacks in the options hash.
- Triggers a "destroy" event on the model, which will bubble up
- through any collections that contain it.
-
-book.destroy({success: function(model, response) { - ... -}}); -- -
- validatemodel.validate(attributes)
-
- This method is left undefined, and you're encouraged to override it with
- your custom validation logic, if you have any that can be performed
- in JavaScript. validate is called before set and
- save, and is passed the attributes that are about to be updated.
- If the model and attributes are valid, don't return anything from validate;
- if the attributes are invalid, return an error of your choosing. It
- can be as simple as a string error message to be displayed, or a complete
- error object that describes the error programmatically. set and
- save will not continue if validate returns an error.
- Failed validations trigger an "error" event.
-
-var Chapter = Backbone.Model.extend({ - validate: function(attrs) { - if (attrs.end < attrs.start) { - return "can't end before it starts"; - } - } -}); - -var one = new Chapter({ - title : "Chapter One: The Beginning" -}); - -one.bind("error", function(model, error) { - alert(model.get("title") + " " + error); -}); - -one.set({ - start: 15, - end: 10 -}); -- -
- "error" 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 - by passing an error callback directly: -
- --account.set({access: "unlimited"}, { - error: function(model, error) { - alert(error); - } -}); -- -
- urlmodel.url()
-
- Returns the relative URL where the model's resource would be located on
- the server. If your models are located somewhere else, override this method
- with the correct logic. Generates URLs of the form: "/[collection.url]/[id]",
- falling back to "/[urlRoot]/id" if the model is not part of a collection.
-
- Delegates to Collection#url to generate the - URL, so make sure that you have it defined, or a urlRoot - property, if all models of this class share a common root URL. - A model with an id of 101, stored in a - Backbone.Collection with a url of "/documents/7/notes", - would have this URL: "/documents/7/notes/101" -
- -
- urlRootmodel.urlRoot
-
- Specify a urlRoot if you're using a model outside of a collection,
- to enable the default url function to generate
- URLs based on the model id. "/[urlRoot]/id"
-
-var Book = Backbone.Model.extend({urlRoot : '/books'}); - -var solaris = new Book({id: "1083-lem-solaris"}); - -alert(solaris.url()); -- -
- parsemodel.parse(response)
-
- parse is called whenever a model's data is returned by the
- server, in fetch, and save.
- The function is passed the raw response object, and should return
- the attributes hash to be set 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.
-
- If you're working with a Rails backend, you'll notice that Rails' default - to_json implementation includes a model's attributes under a - namespace. To disable this behavior for seamless Backbone integration, set: -
- --ActiveRecord::Base.include_root_in_json = false -- -
- clonemodel.clone()
-
- Returns a new instance of the model with identical attributes.
-
- isNewmodel.isNew()
-
- Has this model been saved to the server yet? If the model does not yet have
- an id, it is considered to be new.
-
- changemodel.change()
-
- Manually trigger the "change" event.
- If you've been passing {silent: true} to the set function in order to
- aggregate rapid changes to a model, you'll want to call model.change()
- when you're all finished.
-
- hasChangedmodel.hasChanged([attribute])
-
- Has the model changed since the last "change" event? If an attribute
- is passed, returns true if that specific attribute has changed.
-
- Note that this method, and the following change-related ones, - are only useful during the course of a "change" event. -
- --book.bind("change", function() { - if (book.hasChanged("title")) { - ... - } -}); -- -
- changedAttributesmodel.changedAttributes([attributes])
-
- Retrieve a hash of only the model's attributes that have changed. Optionally,
- an external attributes hash can be passed in, returning
- the attributes in that hash which differ from the model. This can be used
- to figure out which portions of a view should be updated, or what calls
- need to be made to sync the changes to the server.
-
- previousmodel.previous(attribute)
-
- During a "change" event, this method can be used to get the
- previous value of a changed attribute.
-
-var bill = new Backbone.Model({ - name: "Bill Smith" -}); - -bill.bind("change:name", function(model, name) { - alert("Changed name from " + bill.previous("name") + " to " + name); -}); - -bill.set({name : "Bill Jones"}); -- -
- previousAttributesmodel.previousAttributes()
-
- Return a copy of the model's previous attributes. Useful for getting a
- diff between versions of a model, or getting back to a valid state after
- an error occurs.
-
- Collections are ordered sets of models. You can to bind "change" events - to be notified when any model in the collection has been modified, - listen for "add" and "remove" events, fetch - the collection from the server, and use a full suite of - Underscore.js methods. -
- -- Any event that is triggered on a model in a collection will also be - triggered on the collection directly, for convenience. - This allows you to listen for changes to specific attributes in any - model in a collection, for example: - Documents.bind("change:selected", ...) -
- -
- extendBackbone.Collection.extend(properties, [classProperties])
-
- To create a Collection class of your own, extend Backbone.Collection,
- providing instance properties, as well as optional classProperties to be attached
- directly to the collection's constructor function.
-
- modelcollection.model
-
- Override this property to specify the model class that the collection
- contains. If defined, you can pass raw attributes objects (and arrays) to
- add, create,
- and reset, and the attributes will be
- converted into a model of the proper type.
-
-var Library = Backbone.Collection.extend({ - model: Book -}); -- -
- constructor / initializenew Collection([models], [options])
-
- When creating a Collection, you may choose to pass in the initial array of models.
- The collection's comparator function
- may be included as an option. If you define an initialize function, it will be
- invoked when the collection is created.
-
-var tabs = new TabSet([tab1, tab2, tab3]); -- -
- modelscollection.models
-
- Raw access to the JavaScript array of models inside of the collection. Usually you'll
- want to use get, at, or the Underscore methods
- to access model objects, but occasionally a direct reference to the array
- is desired.
-
- toJSONcollection.toJSON()
-
- Return an array containing the attributes hash of each model in 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
- JavaScript's JSON API.
-
-var collection = new Backbone.Collection([ - {name: "Tim", age: 5}, - {name: "Ida", age: 26}, - {name: "Rob", age: 55} -]); - -alert(JSON.stringify(collection)); -- -
- Underscore Methods (25)
-
- Backbone proxies to Underscore.js to provide 25 iteration functions
- on Backbone.Collection. They aren't all documented here, but
- you can take a look at the Underscore documentation for the full details…
-
-Books.each(function(book) { - book.publish(); -}); - -var titles = Books.map(function(book) { - return book.get("title"); -}); - -var publishedBooks = Books.filter(function(book) { - return book.get("published") === true; -}); - -var alphabetical = Books.sortBy(function(book) { - return book.author.get("name").toLowerCase(); -}); -- -
- addcollection.add(models, [options])
-
- Add a model (or an array of models) to the collection. Fires an "add"
- event, which you can pass {silent: true} to suppress. If a
- model property is defined, you may also pass
- raw attributes objects, and have them be vivified as instances of the model.
- Pass {at: index} to splice the model into the collection at the
- specified index.
-
-var ships = new Backbone.Collection; - -ships.bind("add", function(ship) { - alert("Ahoy " + ship.get("name") + "!"); -}); - -ships.add([ - {name: "Flying Dutchman"}, - {name: "Black Pearl"} -]); -- -
- removecollection.remove(models, [options])
-
- Remove a model (or an array of models) from the collection. Fires a
- "remove" event, which you can use silent
- to suppress.
-
- getcollection.get(id)
-
- Get a model from a collection, specified by id.
-
-var book = Library.get(110); -- -
- getByCidcollection.getByCid(cid)
-
- Get a model from a collection, specified by client id. The client id
- is the .cid property of the model, automatically assigned whenever
- a model is created. Useful for models which have not yet been saved to
- the server, and do not yet have true ids.
-
- atcollection.at(index)
-
- Get a model from a collection, specified by index. Useful if your collection
- is sorted, and if your collection isn't sorted, at will still
- retrieve models in insertion order.
-
- lengthcollection.length
-
- Like an array, a Collection maintains a length property, counting
- the number of models it contains.
-
- comparatorcollection.comparator
-
- By default there is no comparator function on a collection.
- If you define a comparator, it will be used to maintain
- the collection in sorted order. This means that as models are added,
- they are inserted at the correct index in collection.models.
- Comparator functions take a model and return a numeric or string value
- by which the model should be ordered relative to others.
-
- Note how even though all of the chapters in this example are added backwards, - they come out in the proper order: -
- --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')); -- -
- Brief aside: This comparator function is different than JavaScript's regular - "sort", which must return 0, 1, or -1, - and is more similar to a sortBy — a much nicer API. -
- -
- sortcollection.sort([options])
-
- Force a collection to re-sort itself. You don't need to call this under
- normal circumstances, as a collection with a comparator function
- will maintain itself in proper sort order at all times. Calling sort
- triggers the collection's "reset" event, unless silenced by passing
- {silent: true}
-
- pluckcollection.pluck(attribute)
-
- Pluck an attribute from each model in the collection. Equivalent to calling
- map, and returning a single attribute from the iterator.
-
-var stooges = new Backbone.Collection([ - new Backbone.Model({name: "Curly"}), - new Backbone.Model({name: "Larry"}), - new Backbone.Model({name: "Moe"}) -]); - -var names = stooges.pluck("name"); - -alert(JSON.stringify(names)); -- -
- urlcollection.url or collection.url()
-
- Set the url property (or function) on a collection to reference
- its location on the server. Models within the collection will use url
- to construct URLs of their own.
-
-var Notes = Backbone.Collection.extend({ - url: '/notes' -}); - -// Or, something more sophisticated: - -var Notes = Backbone.Collection.extend({ - url: function() { - return this.document.url() + '/notes'; - } -}); -- -
- parsecollection.parse(response)
-
- parse is called by Backbone whenever a collection's models are
- returned by the server, in fetch.
- The function is passed the raw response object, and should return
- the array of model attributes to be added
- 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.
-
-var Tweets = Backbone.Collection.extend({ - // The Twitter Search API returns tweets under "results". - parse: function(response) { - return response.results; - } -}); -- -
- fetchcollection.fetch([options])
-
- Fetch the default set of models for this collection from the server,
- resetting the collection when they arrive. The options hash takes
- success and error
- callbacks which will be passed (collection, response) as arguments.
- When the model data returns from the server, the collection will
- reset.
- Delegates to Backbone.sync
- under the covers, for custom persistence strategies.
- The server handler for fetch requests should return a JSON array of
- models.
-
-Backbone.sync = function(method, model) { - alert(method + ": " + model.url); -}; - -var Accounts = new Backbone.Collection; -Accounts.url = '/accounts'; - -Accounts.fetch(); -- -
- If you'd like to add the incoming models to the current collection, instead - of replacing the collection's contents, pass {add: true} as an - option to fetch. -
- -- jQuery.ajax options can also be passed directly as fetch options, - so to fetch a specific page of a paginated collection: - Documents.fetch({data: {page: 3}}) -
- -- Note that fetch should not be used to populate collections on - page load — all models needed at load time should already be - bootstrapped in to place. fetch is - intended for lazily-loading models for interfaces that are not needed - immediately: for example, documents with collections of notes that may be - toggled open and closed. -
- -
- resetcollection.reset(models, [options])
-
- 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 reset to replace a collection with a new list
- of models (or attribute hashes), triggering a single "reset" event
- at the end. Pass {silent: true} to suppress the "reset" event.
- Using reset with no arguments is useful as a way to empty the collection.
-
- Here's an example using reset to bootstrap a collection during initial page load, - in a Rails application. -
- --<script> - Accounts.reset(<%= @accounts.to_json %>); -</script> -- -
- Calling collection.reset() without passing any models as arguments - will empty the entire collection. -
- -
- createcollection.create(attributes, [options])
-
- Convenience to create a new instance of a model within a collection.
- Equivalent to instantiating a model with a hash of attributes,
- saving the model to the server, and adding the model to the set after being
- successfully created. Returns
- the model, or false if a validation error prevented the
- model from being created. In order for this to work, you should set the
- model property of the collection.
- The create method can accept either an attributes hash or an
- existing, unsaved model object.
-
-var Library = Backbone.Collection.extend({ - model: Book -}); - -var NYPL = new Library; - -var othello = NYPL.create({ - title: "Othello", - author: "William Shakespeare" -}); -- -
- Web applications often choose to change their URL fragment (#fragment) - in order to provide shareable, bookmarkable URLs for an Ajax-heavy application. - Backbone.Router provides methods for routing client-side URL - fragments, and connecting them to actions and events. -
- -- During page load, after your application has finished creating all of its routers, - be sure to call Backbone.history.start(), or - Backbone.history.start({pushState: true}) to route the initial URL. -
- -
- extendBackbone.Router.extend(properties, [classProperties])
-
- Get started by creating a custom router class. You'll
- want to define actions that are triggered when certain URL fragments are
- matched, and provide a routes hash
- that pairs routes to actions.
-
-var Workspace = Backbone.Router.extend({ - - routes: { - "help": "help", // #help - "search/:query": "search", // #search/kiwis - "search/:query/p:page": "search" // #search/kiwis/p7 - }, - - help: function() { - ... - }, - - search: function(query, page) { - ... - } - -}); -- -
- routesrouter.routes
-
- The routes hash maps URLs with parameters to functions on your router,
- similar to the View's events hash.
- Routes can contain parameter parts, :param, which match a single URL
- component between slashes; and splat parts *splat, which can match
- any number of URL components.
-
- For example, a route of "search/:query/p:page" will match - a fragment of #search/obama/p2, passing "obama" - and "2" to the action. A route of "file/*path" will - match #file/nested/folder/file.txt, - passing "nested/folder/file.txt" to the action. -
- -- When the visitor presses the back button, or enters a URL, and a particular - route is matched, the name of the action will be fired as an - event, so that other objects can listen to the router, - and be notified. In the following example, visiting #help/uploading - will fire a route:help event from the router. -
- --routes: { - "help/:page": "help", - "download/*path": "download", - "folder/:name": "openFolder", - "folder/:name-:mode": "openFolder" -} -- -
-router.bind("route:help", function(page) { - ... -}); -- -
- constructor / initializenew Router([options])
-
- When creating a new router, you may pass its
- routes hash directly as an option, if you
- choose. All options will also be passed to your initialize
- function, if defined.
-
- routerouter.route(route, name, callback)
-
- Manually create a route for the router, The route argument may
- be a routing string or regular expression.
- Each matching capture from the route or regular expression will be passed as
- an argument to the callback. The name argument will be triggered as
- a "route:name" event whenever the route is matched.
-
-initialize: function(options) { - - // Matches #page/10, passing "10" - this.route("page/:number", "page", function(number){ ... }); - - // Matches /117-a/b/c/open, passing "117-a/b/c" - this.route(/^(.*?)\/open$/, "open", function(id){ ... }); - -} -- - - -
-openPage: function(pageNumber) { - this.document.pages.at(pageNumber).open(); - this.navigate("page/" + pageNumber); -} - -# Or ... - -app.navigate("help/troubleshooting", true); -- -
- History serves as a global router (per frame) to handle hashchange - events or pushState, match the appropriate route, and trigger callbacks. You shouldn't - ever have to create one of these yourself — you should use the reference - to Backbone.history that will be created for you automatically if you make use - of Routers with routes. -
- -- pushState support exists on a purely opt-in basis in Backbone. - Older browsers that don't support pushState will continue to use - hash-based URL fragments, and if a hash URL is visited by a - pushState-capable browser, it will be transparently upgraded to - the true URL. Note that using real URLs requires your web server to be - able to correctly render those pages, so back-end changes are required - as well. For example, if you have a route of /documents/100, - your web server must be able to serve that page, if the browser - visits that URL directly. For full search-engine crawlability, it's best to - have the server generate the complete HTML for the page ... but if it's a web - application, just rendering the same content you would have for the root URL, - and filling in the rest with Backbone Views and JavaScript works fine. -
- -
- startBackbone.history.start([options])
-
- When all of your Routers have been created,
- and all of the routes are set up properly, call Backbone.history.start()
- to begin monitoring hashchange events, and dispatching routes.
-
- To indicate that you'd like to use HTML5 pushState support in - your application, use Backbone.history.start({pushState: true}). -
- -- If your application is not being served from the root url / of your - domain, be sure to tell History where the root really is, as an option: - Backbone.history.start({pushState: true, root: "/public/search/"}) -
- When called, if a route succeeds with a match for the current URL, - Backbone.history.start() returns true. If no defined - route matches the current URL, it returns false. -
- --$(function(){ - new WorkspaceRouter(); - new HelpPaneRouter(); - Backbone.history.start({pushState: true}); -}); -- -
- Backbone.sync is the function that Backbone calls every time it - attempts to read or save a model to the server. By default, it uses - (jQuery/Zepto).ajax to make a RESTful JSON request. You can override - it in order to use a different persistence strategy, such as WebSockets, - XML transport, or Local Storage. -
- -- The method signature of Backbone.sync is sync(method, model, [options]) -
- -- With the default implementation, when Backbone.sync sends up a request to save - a model, its attributes will be passed, serialized as JSON, and sent in the HTTP body - with content-type application/json. When returning a JSON response, - send down the attributes of the model that have been changed by the server, and need - to be updated on the client. When responding to a "read" request from a collection - (Collection#fetch), send down an array - of model attribute objects. -
- -- The default sync handler maps CRUD to REST like so: -
- -- As an example, a Rails handler responding to an "update" call from - Backbone might look like this: (In real code, never use - update_attributes blindly, and always whitelist the attributes - you allow to be changed.) -
- --def update - account = Account.find params[:id] - account.update_attributes params - render :json => account -end -- -
- One more tip for Rails integration is to disable the default namespacing for - to_json calls on models by setting ActiveRecord::Base.include_root_in_json = false -
- -
- emulateHTTPBackbone.emulateHTTP = true
-
- If you want to work with a legacy web server that doesn't support Backbones's
- default REST/HTTP approach, you may choose to turn on Backbone.emulateHTTP.
- Setting this option will fake PUT and DELETE requests with
- a HTTP POST, and pass them under the _method parameter. Setting this option
- will also set an X-HTTP-Method-Override header with the true method.
-
-Backbone.emulateHTTP = true; - -model.save(); // POST to "/collection/id", with "_method=PUT" + header. -- -
- emulateJSONBackbone.emulateJSON = true
-
- If you're working with a legacy web server that can't handle requests
- encoded as application/json, setting Backbone.emulateJSON = true;
- will cause the JSON to be serialized under a model parameter, and
- the request to be made with a application/x-www-form-urlencoded
- mime type, as if from an HTML form.
-
- Backbone views are almost more convention than they are code — they - don't determine anything about your HTML or CSS for you, and can be used - with any JavaScript templating library. - The general idea is to organize your interface into logical views, - backed by models, each of which can be updated independently when the - model changes, without having to redraw the page. Instead of digging into - a JSON object, looking up an element in the DOM, and updating the HTML by hand, - you can bind your view's render function to the model's "change" - event — and now everywhere that - model data is displayed in the UI, it is always immediately up to date. -
- -
- extendBackbone.View.extend(properties, [classProperties])
-
- Get started with views by creating a custom view class. You'll want to
- override the render function, specify your
- declarative events, and perhaps the
- tagName, className, or id of the View's root
- element.
-
-var DocumentRow = Backbone.View.extend({ - - tagName: "li", - - className: "document-row", - - events: { - "click .icon": "open", - "click .button.edit": "openEditDialog", - "click .button.delete": "destroy" - }, - - initialize: function() { - _.bindAll(this, "render"); - }, - - render: function() { - ... - } - -}); -- -
- constructor / initializenew View([options])
-
- When creating a new View, the options you pass are attached to the view
- as this.options, for future reference. There are several special
- options that, if passed, will be attached directly to the view:
- model, collection,
- el, id, className, and tagName.
- If the view defines an initialize function, it will be called when
- 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:
- new View({el: existingElement})
-
-var doc = Documents.first(); - -new DocumentRow({ - model: doc, - id: "document-row-" + doc.id -}); -- -
- elview.el
-
- All views have a DOM element at all times (the el property),
- whether they've already been inserted into the page or not. In this
- fashion, views can be rendered at any time, and inserted into the DOM all
- at once, in order to get high-performance UI rendering with as few
- reflows and repaints as possible. this.el is created from the
- view's tagName, className, and id properties,
- if specified. If not, el is an empty div.
-
- You may assign el directly if the view is being - created for an element that already exists in the DOM. Use either a - reference to a real DOM element, or a css selector string. -
- --var ItemView = Backbone.View.extend({ - tagName: 'li' -}); - -var BodyView = Backbone.View.extend({ - el: 'body' -}); - -var item = new ItemView(); -var body = new BodyView(); - -alert(item.el + ' ' + body.el); -- -
- $ (jQuery or Zepto)view.$(selector)
-
- If jQuery or Zepto is included on the page, each view has a
- $ function that runs queries scoped within the view's element. If you use this
- scoped jQuery function, you don't have to use model ids as part of your query
- to pull out specific elements in a list, and can rely much more on HTML class
- attributes. It's equivalent to running: $(selector, this.el)
-
-ui.Chapter = Backbone.View.extend({ - serialize : function() { - return { - title: this.$(".title").text(), - start: this.$(".start-page").text(), - end: this.$(".end-page").text() - }; - } -}); -- -
- renderview.render()
-
- The default implementation of render is a no-op. Override this
- function with your code that renders the view template from model data,
- and updates this.el with the new HTML. A good
- convention is to return this at the end of render to
- enable chained calls.
-
-var Bookmark = Backbone.View.extend({ - render: function() { - $(this.el).html(this.template(this.model.toJSON())); - return this; - } -}); -- -
- Backbone is agnostic with respect to your preferred method of HTML templating. - Your render function could even munge together an HTML string, or use - document.createElement to generate a DOM tree. However, we suggest - choosing a nice JavaScript templating library. - Mustache.js, - Haml-js, and - Eco are all fine alternatives. - Because Underscore.js is already on the page, - _.template - is available, and is an excellent choice if you've already XSS-sanitized - your interpolated data. -
- -- Whatever templating strategy you end up with, it's nice if you never - have to put strings of HTML in your JavaScript. At DocumentCloud, we - use Jammit in order - to package up JavaScript templates stored in /app/views as part - of our main core.js asset package. -
- -
- removeview.remove()
-
- Convenience function for removing the view from the DOM. Equivalent to calling
- $(view.el).remove();
-
- makeview.make(tagName, [attributes], [content])
-
- Convenience function for creating a DOM element of the given type (tagName),
- with optional attributes and HTML content. Used internally to create the
- initial view.el.
-
-var view = new Backbone.View; - -var el = view.make("b", {className: "bold"}, "Bold! "); - -$("#make-demo").append(el); -- - - -
- delegateEventsdelegateEvents([events])
-
- Uses jQuery's delegate function to provide declarative callbacks
- for DOM events within a view.
- If an events hash is not passed directly, uses this.events
- as the source. Events are written in the format {"event selector": "callback"}.
- Omitting the selector causes the event to be bound to the view's
- root element (this.el). By default, delegateEvents is called
- within the View's constructor for you, so if you have a simple events
- hash, all of your DOM events will always already be connected, and you will
- never have to call this function yourself.
-
- Using delegateEvents provides a number of advantages over manually - using jQuery to bind events to child elements during render. All attached - callbacks are bound to the view before being handed off to jQuery, so when - the callbacks are invoked, this continues to refer to the view object. When - delegateEvents is run again, perhaps with a different events - hash, all callbacks are removed and delegated afresh — useful for - views which need to behave differently when in different modes. -
- -- A view that displays a document in a search result might look - something like this: -
- --var DocumentView = Backbone.View.extend({ - - events: { - "dblclick" : "open", - "click .icon.doc" : "select", - "contextmenu .icon.doc" : "showMenu", - "click .show_notes" : "toggleNotes", - "click .title .lock" : "editAccessLevel", - "mouseover .title .date" : "showTooltip" - }, - - render: function() { - $(this.el).html(this.template(this.model.toJSON())); - return this; - }, - - open: function() { - window.open(this.model.get("viewer_url")); - }, - - select: function() { - this.model.set({selected: true}); - }, - - ... - -}); -- -
- -
- -
- noConflictvar backbone = Backbone.noConflict();
-
- Returns the Backbone object back to its original value. You can
- use the return value of Backbone.noConflict() to keep a local
- reference to Backbone. Useful for embedding Backbone on third-party
- websites, where you don't want to clobber the existing Backbone.
-
-var localBackbone = Backbone.noConflict(); -var model = localBackbone.Model.extend(...); -- -
- Jérôme Gravel-Niquet has contributed a - Todo List application - that is bundled in the repository as Backbone example. If you're wondering - where to get started with Backbone in general, take a moment to - read through the annotated source. The app uses a - LocalStorage adapter - to transparently save all of your todos within your browser, instead of - sending them to a server. Jérôme also has a version hosted at - localtodos.com that uses a - MooTools-backed version of Backbone - instead of jQuery. -
- -- The DocumentCloud workspace - is built on Backbone.js, with Documents, Projects, - Notes, and Accounts all as Backbone models and collections. - If you're interested in history — both Underscore.js and Backbone.js - were originally extracted from the DocumentCloud codebase, and packaged - into standalone JS libraries. -
- -- 37Signals used Backbone.js to create - Basecamp Mobile, the mobile version - of their popular project management software. You can access all your Basecamp - projects, post new messages, and comment on milestones (all represented - internally as Backbone.js models). -
- -- MetaLab used Backbone.js to create - Flow, a task management app for teams. The - workspace relies on Backbone.js to construct task views, activities, accounts, - folders, projects, and tags. You can see the internals under window.Flow. -
- -- CloudApp is simple file and link - sharing for the Mac. Backbone.js powers the web tools - which consume the documented API - to manage Drops. Data is either pulled manually or pushed by - Pusher and fed to - Mustache templates for - rendering. Check out the annotated source code - to see the magic. -
- -- SoundCloud is the leading sound sharing - platform on the internet, and Backbone.js provides the foundation for - Mobile SoundCloud. The project uses - the public SoundCloud API - as a data source (channeled through a nginx proxy), - jQuery templates - for the rendering, Qunit - and PhantomJS for - the testing suite. The JS code, templates and CSS are built for the - production deployment with various Node.js tools like - ready.js, - Jake, - jsdom. - The Backbone.History was modified to support the HTML5 history.pushState. - Backbone.sync was extended with an additional SessionStorage based cache - layer. -
- -- Coding Staff used Backbone.js to - create Quote Roller, an application - that helps to create, send, organize and track business proposals with ease. - Backbone.js has been used to implement interactive parts of the - application like template builder, pricing table, file attachments manager. -
- -- Our fellow - Knight Foundation News Challenge - winners, MapBox, created an open-source - map design studio with Backbone.js: - TileMill. - TileMill lets you manage map layers based on shapefiles and rasters, and - edit their appearance directly in the browser with the - Carto styling language. - Note that the gorgeous MapBox homepage - is also a Backbone.js app. -
- -- Aaron Hamid and - Michal Kuklis from - Incandescent Software - used Backbone.js to create - Menagerie Whiteboard a digital - "whiteboard" for veterinary practices. Backbone Models were used to - sync the data with CouchDB. A Backbone Controller was used for - routing and bookmarkable deep links. Backbone Views were used to - bind, listen and 'react' to changes coming from models. - Backbone.sync was extended to support connection to CouchDB - and deployment as a CouchApp. -
- -- Elliott Kember and - Hector Simpson built - Insta-great! - - a fun way to explore popular photos and interact with - Instagram on the web. - Elliott says, "Backbone.js and Coffeescript were insanely useful for - writing clean, consistent UI code and keeping everything modular and - readable, even through several code refactors. I'm in love." -
- -- Decide.com helps people decide when to buy - consumer electronics. It relies heavily on Backbone.js to render and - update its Search Results Page. An "infinite scroll" feature takes - advantage of a SearchResults model containing a collection of - Product models to fetch more results and render them on the fly - with Mustache. A SearchController keeps everything in sync and - maintains page state in the URL. Backbone also powers the user - accounts and settings management. -
- -- BitTorrent used Backbone to - completely rework an existing Win32 UI. Models normalize access to the - client's data and views rely heavily on the change events to keep - the UI state current. Using Backbone and SCSS, - our new design and UX - prototypes are considerably easier to iterate, test and work with than - the original Win32 UI. -
- -- Fluxiom uses Backbone.js and HTML5 to - deliver a seamless upload experience from the desktop to the cloud, - including drag and drop, live previews, partial uploads, and one-click sharing. -
- -
- The upload queue is a single collection and each file is it’s own model. - The UI is divided into several views for efficient event handling, and - uses Underscore.js - templates for fast rendering, even when handling hundreds of uploads. -
- -- Chop is a little app from - ZURB that lets people slice up bad code - and share their feedback to help put it back together. - Chop was built to demonstrate how easy it is to build pageless apps - using Backbone.js and Rails. Chop makes extensive use of Backbone Views, - Controllers, and Models. -
- -- James Yu used Backbone.js to - create QuietWrite, an app - that gives writers a clean and quiet interface to concentrate on the text itself. - The editor relies on Backbone to persist document data to the server. He - followed up with a Backbone.js + Rails tutorial that describes how to implement - CloudEdit, a simple document editing app. -
- -- Cristi Balan and - Irina Dumitrascu created - Tzigla, a collaborative drawing - application where artists make tiles that connect to each other to - create surreal drawings. - Backbone models help organize the code, routers provide - bookmarkable deep links, - and the views are rendered with - haml.js and - Zepto. - Tzigla is written in Ruby (Rails) on the backend, and - CoffeeScript on the frontend, with - Jammit - prepackaging the static assets. -
- -- Michael Aufreiter is building an open source document authoring and - publishing engine: Substance. - Substance makes use of Backbone.View and Backbone.Router, while - Backbone plays well together with - Data.js, which is used for - data persistence. -
- -
- Catalog of Events
-
- Here's a list of all of the built-in events that Backbone.js can fire.
- You're also free to trigger your own events on Models and Views as you
- see fit.
-
- Nested Models & Collections
-
- It's common to nest collections inside of models with Backbone. For example,
- consider a Mailbox model that contains many Message models.
- One nice pattern for handling this is have a this.messages collection
- for each mailbox, enabling the lazy-loading of messages, when the mailbox
- is first opened ... perhaps with MessageList views listening for
- "add" and "remove" events.
-
-var Mailbox = Backbone.Model.extend({ - - initialize: function() { - this.messages = new Messages; - this.messages.url = '/mailbox/' + this.id + '/messages'; - this.messages.bind("reset", this.updateCounts); - }, - - ... - -}); - -var Inbox = new Mailbox; - -// And then, when the Inbox is opened: - -Inbox.messages.fetch(); -- -
- If you're looking for something more opinionated, there are a number of - Backbone plugins that add sophisticated associations among models, - available on the wiki. -
- -
- Loading Bootstrapped Models
-
- When your app first loads, it's common to have a set of initial models that
- you know you're going to need, in order to render the page. Instead of
- firing an extra AJAX request to fetch them,
- a nicer pattern is to have their data already bootstrapped into the page.
- You can then use reset to populate your
- collections with the initial data. At DocumentCloud, in the
- ERB template for the
- workspace, we do something along these lines:
-
-<script> - Accounts.reset(<%= @accounts.to_json %>); - Projects.reset(<%= @projects.to_json(:collaborators => true) %>); -</script> -- -
- How does Backbone relate to "traditional" MVC?
-
- Different implementations of the
- Model-View-Controller
- pattern tend to disagree about the definition of a controller. If it helps any, in
- Backbone, the View class can also be thought of as a
- kind of controller, dispatching events that originate from the UI, with
- the HTML template serving as the true view. We call it a View because it
- represents a logical chunk of UI, responsible for the contents of a single
- DOM element.
-
- Comparing the overall structure of Backbone to a server-side MVC framework - like Rails, the pieces line up like so: -
- -
- Binding "this"
-
- Perhaps the single most common JavaScript "gotcha" is the fact that when
- you pass a function as a callback, its value for this is lost. With
- Backbone, when dealing with events and callbacks,
- you'll often find it useful to rely on
- _.bind and
- _.bindAll
- from Underscore.js. _.bind takes a function and an object to be
- used as this, any time the function is called in the future.
- _.bindAll takes an object and a list of method names: each method
- in the list will be bound to the object, so that its this may
- not change. For example, in a View that listens for
- changes to a collection...
-
-var MessageList = Backbone.View.extend({ - - initialize: function() { - _.bindAll(this, "addMessage", "removeMessage", "render"); - - var messages = this.collection; - messages.bind("reset", this.render); - messages.bind("add", this.addMessage); - messages.bind("remove", this.removeMessage); - } - -}); - -// Later, in the app... - -Inbox.messages.add(newMessage); -- -
- 0.5.1 — July 5, 2011
- Cleanups from the 0.5.0 release, to wit: improved transparent upgrades from
- hash-based URLs to pushState, and vice-versa. Fixed inconsistency with
- non-modified attributes being passed to Model#initialize. Reverted
- a 0.5.0 change that would strip leading hashbangs from routes.
- Added contains as an alias for includes.
-
- 0.5.0 — July 1, 2011
- A large number of tiny tweaks and micro bugfixes, best viewed by looking
- at the commit diff.
- HTML5 pushState support, enabled by opting-in with:
- Backbone.history.start({pushState: true}).
- Controller was renamed to Router, for clarity.
- Collection#refresh was renamed to Collection#reset to emphasize
- its ability to both reset the collection with new models, as well as empty
- out the collection when used with no parameters.
- saveLocation was replaced with navigate.
- RESTful persistence methods (save, fetch, etc.) now return the jQuery deferred
- object for further success/error chaining and general convenience.
- Improved XSS escaping for Model#escape.
- Added a urlRoot option to allow specifying RESTful urls without
- the use of a collection.
- An error is thrown if Backbone.history.start is called multiple times.
- Collection#create now validates before initializing the new model.
- view.el can now be a jQuery string lookup.
- Backbone Views can now also take an attributes parameter.
- Model#defaults can now be a function as well as a literal attributes
- object.
-
- 0.3.3 — Dec 1, 2010
- Backbone.js now supports Zepto, alongside
- jQuery, as a framework for DOM manipulation and Ajax support.
- Implemented Model#escape, to efficiently handle
- attributes intended for HTML interpolation. When trying to persist a model,
- failed requests will now trigger an "error" event. The
- ubiquitous options argument is now passed as the final argument
- to all "change" events.
-
- 0.3.2 — Nov 23, 2010
- Bugfix for IE7 + iframe-based "hashchange" events. sync may now be
- overridden on a per-model, or per-collection basis. Fixed recursion error
- when calling save with no changed attributes, within a
- "change" event.
-
- 0.3.1 — Nov 15, 2010
- All "add" and "remove" events are now sent through the
- model, so that views can listen for them without having to know about the
- collection. Added a remove method to Backbone.View.
- toJSON is no longer called at all for 'read' and 'delete' requests.
- Backbone routes are now able to load empty URL fragments.
-
- 0.3.0 — Nov 9, 2010
- Backbone now has Controllers and
- History, for doing client-side routing based on
- URL fragments.
- Added emulateHTTP to provide support for legacy servers that don't
- do PUT and DELETE.
- Added emulateJSON for servers that can't accept application/json
- encoded requests.
- Added Model#clear, which removes all attributes
- from a model.
- All Backbone classes may now be seamlessly inherited by CoffeeScript classes.
-
- 0.2.0 — Oct 25, 2010
- Instead of requiring server responses to be namespaced under a model
- key, now you can define your own parse method
- to convert responses into attributes for Models and Collections.
- The old handleEvents function is now named
- delegateEvents, and is automatically
- called as part of the View's constructor.
- Added a toJSON function to Collections.
- Added Underscore's chain to Collections.
-
- 0.1.2 — Oct 19, 2010
- Added a Model#fetch method for refreshing the
- attributes of single model from the server.
- An error callback may now be passed to set and save
- as an option, which will be invoked if validation fails, overriding the
- "error" event.
- You can now tell backbone to use the _method hack instead of HTTP
- methods by setting Backbone.emulateHTTP = true.
- Existing Model and Collection data is no longer sent up unnecessarily with
- GET and DELETE requests. Added a rake lint task.
- Backbone is now published as an NPM module.
-
- 0.1.1 — Oct 14, 2010
- Added a convention for initialize functions to be called
- upon instance construction, if defined. Documentation tweaks.
-
- 0.1.0 — Oct 13, 2010
- Initial Backbone release.
-
-
-
-
-
-
t |