Backbone.js gives structure to web 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 API over a RESTful JSON interface.
简而言之,Backbone.js是一个可以在前端组织MVC的javascript框架。
写的Javascript代码一旦多起来,没有一个好的组织,那就会像噩梦一样。
Backbone提供了Models, Collections, Views。Models 用来创建数据,校验数据,绑定事件,存储数据到服务器端;Collections 包含你创建的 functions;Views 用来展示数据。如此这般,在前端也做到了数据和显示分离。
Backbone依赖于Underscore.js,这是一个有很多常用函数的js文件(很好用).
与backbone.js类似的还有AngularJS,同样为js的mvc框架,两者对比:http://www.zhihu.com/question/21170137。
backbone应用场景:http://www.zhihu.com/question/19720745
Backbone's only hard dependency is Underscore.js ( >= 1.5.0). For RESTful persistence, history support via Backbone.Router and DOM manipulation with Backbone.View, include jQuery, and json2.js for older Internet Explorer support. (Mimics of the Underscore and jQuery APIs, such as Lo-Dash and Zepto, will also tend to work, with varying degrees of compatibility.)
helloworld教程:http://arturadib.com/hello-backbonejs/
html模板:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>hello-backbonejs</title> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.js"></script> <script src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min.js"></script> <script src="1.js"></script> </body> </html>
example1:This example illustrates the declaration and instantiation of a minimalist View
(function($){ // **ListView class**: Our main app view. var ListView = Backbone.View.extend({ el: $('body'), // attaches `this.el` to an existing element. // `initialize()`: Automatically called upon instantiation. Where you make all types of bindings, _excluding_ UI events, such as clicks, etc. initialize: function(){ _.bindAll(this, 'render'); // fixes loss of context for 'this' within methods this.render(); // not all views are self-rendering. This one is. }, // `render()`: Function in charge of rendering the entire view in `this.el`. Needs to be manually called by the user. render: function(){ $(this.el).append("<ul> <li>hello world</li> </ul>"); } }); // **listView instance**: Instantiate main app view. var listView = new ListView(); })(jQuery);
This example illustrates the binding of DOM events to View methods.
Working example: 2.html.
// (function($){ var ListView = Backbone.View.extend({ el: $('body'), // el attaches to existing element // `events`: Where DOM events are bound to View methods. Backbone doesn't have a separate controller to handle such bindings; it all happens in a View. events: { 'click button#add': 'addItem' }, initialize: function(){ _.bindAll(this, 'render', 'addItem'); // every function that uses 'this' as the current object should be in here this.counter = 0; // total number of items added thus far this.render(); }, // `render()` now introduces a button to add a new list item. render: function(){ $(this.el).append("<button id='add'>Add list item</button>"); $(this.el).append("<ul></ul>"); }, // `addItem()`: Custom function called via `click` event above. addItem: function(){ this.counter++; $('ul', this.el).append("<li>hello world"+this.counter+"</li>"); } }); var listView = new ListView(); })(jQuery);
events
: Where DOM events are bound to View methods. Backbone doesn't have a separate controller to handle such bindings; it all happens in a View.
(function($){ // **Item class**: The atomic part of our Model. A model is basically a Javascript object, i.e. key-value pairs, with some helper functions to handle event triggering, persistence, etc. var Item = Backbone.Model.extend({ defaults: { part1: 'hellosdf', part2: 'worlsdfd' } }); // **List class**: A collection of `Item`s. Basically an array of Model objects with some helper functions. var List = Backbone.Collection.extend({ model: Item }); var ListView = Backbone.View.extend({ el: $('body'), events: { 'click button#add': 'addItem' }, // `initialize()` now instantiates a Collection, and binds its `add` event to own method `appendItem`. (Recall that Backbone doesn't offer a separate Controller for bindings...). initialize: function(){ _.bindAll(this, 'render', 'addItem', 'appendItem'); // remember: every function that uses 'this' as the current object should be in here this.collection = new List(); this.collection.bind('add', this.appendItem); // collection event binder this.counter = 0; this.render(); }, render: function(){ // Save reference to `this` so it can be accessed from within the scope of the callback below var self = this; $(this.el).append("<button id='add'>Add list item</button>"); $(this.el).append("<ul></ul>"); _(this.collection.models).each(function(item){ // in case collection is not empty self.appendItem(item); }, this); }, // `addItem()` now deals solely with models/collections. View updates are delegated to the `add` event listener `appendItem()` below. addItem: function(){ this.counter++; var item = new Item(); item.set({ part2: item.get('part2') + this.counter // modify item defaults }); this.collection.add(item); // add item to collection; view is updated via event 'add' }, // `appendItem()` is triggered by the collection event `add`, and handles the visual update. appendItem: function(item){ $('ul', this.el).append("<li>"+item.get('part1')+" "+item.get('part2')+"</li>"); } }); var listView = new ListView(); })(jQuery);
Item class: The atomic part of our Model. A model is basically a Javascript object, i.e. key-value pairs, with some helper functions to handle event triggering, persistence, etc.
List class: A collection of Item
s. Basically an array of Model objects with some helper functions.
underscore bindAll:
bindAll_.bindAll(object, *methodNames)
Binds a number of methods on the object, specified by methodNames, to be run in the context of that object whenever they are invoked. Very handy for binding functions that are going to be used as event handlers, which would otherwise be invoked with a fairly useless this. methodNames are required.
var buttonView = { label : 'underscore', onClick: function(){ alert('clicked: ' + this.label); }, onHover: function(){ console.log('hovering: ' + this.label); } }; _.bindAll(buttonView, 'onClick', 'onHover'); // When the button is clicked, this.label will have the correct value. jQuery('#underscore_button').bind('click', buttonView.onClick);
demo4:This example illustrates how to delegate the rendering of a Model to a dedicated View.