中文API:http://www.csser.com/tools/backbone/backbone.js.html javascript
英文API:http://backbonejs.org/ css
Backbone是构建javascript应用程序的一个优秀的类库。他简洁、轻量级、功能实在。 html
backbone采用MVC模式,自己提供了模型、控制器和视图从而咱们应用程序的骨架便造成。 java
backbone依赖于underscore,他是一个类库,提供了60多个函数处理数组操做、函数绑定,以及javascript模板机制。 node
模型 数组
模型是保存应用程序数据的地方。咱们能够把模型看作对应用程序原始数据的精心抽象,而且添加了一些工具函数和事件。 函数
咱们可使用Backbone.Model的extend方法来建立Backbone模型: 工具
var Note = Backbone.Model.extend({ defaults:{ title:’’//用于定义属性的 created_at:new Date(); //定义一个时间的对象 }, initialize: function () { }, //当即执行函数一直处于监听的状态 validate: functin () { }, //验证 });
第二个参数是可选的类属性的哈希,经过屡次调用extend能够生成模型的子类,他们将继承父亲全部类和实例属性: this
var Note = Backbone.Model.extend({ //实例属性 instanceProperty: 'foo'}, { //类属性 classProperty: 'bar'}); assertEqual(User.instanceProperty, 'foo'); assertEqual(User.classProperty, 'bar');
当模型实例化时,他的initialize方法能够接受任意实例参数,其工做原理是backbone模型自己就是构造函数,因此可使用new生成实例: spa
var Note = Backbone.Model.extend({ initialize: function (name) { //模型实例化时会马上执行 this.set({name: name}); } }); var note = new Note('Mickey'); assertEqual(note.get('name'), 'Mickey');
Ps: assertEqual用于判断相等
模型和属性
使用set和get方法设置获取实例的属性:
var note = new Note(); note.set({ name: 'Mickey' }); note.get('name'); //Mickey user.attributes;//{name: 'Mickey'}
咱们看到其实user.arributes是一个对象字面量,咱们不会直接操做他,由于咱们使用get/set方法能够进行咱们的验证流程。
使用clear方法清除实例的属性
var note = new Note(); note.set({ name: 'Mickey' }); note.clear(); //清除note的所有属性
判断实例是否有某个属性或者返回某个属性
var note = new Note(); note.set({ name: 'Mickey' }); note.has(‘name’) //判断实例是否有name的属性 note.get(‘name’) //返回note实例的title属性值
咱们使用validate方法来校验一个实例属性,默认状况没有任何验证,如果咱们须要验证的话:
var Note = Backbone.Model.extend({ validate: function (attr,options) { if (!attr.name || attr.name.length < 3) { return '名称不能为空或者小于3'; } } });
若是属性合法,validate不会理睬之,不合法能够返回错误字符串或者Error对象,校验失败get/set方法就会触发error事件:
var note = new Note(); note.bind('error', function (model, error) { //错误处理函数}); note.set({ name: 'm' });//给特定集合添加一个错误处理程序note.set({ name: 'm' }, { error: function (model, error) { } });
固然咱们也能够在initializa里面添加对错误事件的处理
initialize: function () { //当验证失败的时候当即执行该函数 this.on (‘invalid’,function ( model, error ) { console.log ( error ) } //其余事件实例 this.on(‘change’,function (model,options) { //当属性发生变化的时候触发该函数 console.log ( ‘实例属性发生了变化’ ) } //当 ‘change’ 改成 ‘change:name’时 则仅当name属性发生变化时触发 }
var NoteModel = Backbone.Model.extend({ defaults: { name: 'Mickey'} }); assertEqual((new Chat).get('name'), 'Mickey');
集合
在backbone中,模型实例的数据存放在多个集合中,为何模型之间要使用独立的集合,其缘由有点复杂,但在实际中咱们常常这么作(虽然我还没作过)。
var Collection = Backbone.Collection.extend({ model: Node //用于规定node的类型 initialize: function (){} //实例化集合时当即执行的函数 });
在上面的例子中,咱们覆盖了model属性来指定与集合相关联的模型(这里是Node模型),虽然这个步骤不是必须的,可是为该集合设置一个默认的模型指向每每能派上大用场。
一般集合会包含单个模型的一个实例,而不是不一样模型的多个实例。
在建立一个集合时,能够传递一个模型数组,好比backbone模型,若是定义了一个初始化实例函数,在初始化时就会调用之:
var collections = new Collection([{ name: 'Mickey' }, { name: 'Miki'}]);
另外一种方法是使用add方法为集合添加模型:
collections.add({ name: 'Mickey' }); collections.add([{ name: 'Mickey' }, { name: 'Mcikey' }]);
还有一种方法就是先实例化模型再加入
var note1 = new Note ({name:’mickey’}); var note2 = new Note ({name:’Miki’}); var collections = new Collection ([note1,note2]);
当传递一个对象时,若是该对象已经存在,则默认不会覆盖,除非设置merge
//此处假设Note模型中有id属性 var collections = new Collection; collections.add ({id:1, name:’mickey’}) collections.add ({id:1, name:’miki’}) //此时collections中并不存在miki collections.add ({id:1, name:’miki’}, {merge:true}) //此时id为1的模型的name为//miki
一些模型的基本操做
var note1 = new Node({name:’mickey’}) var note2 = new Node({name:’miki’}) var note3 = new Node({name:’js’}) var collections = new Collection ([note1,note2])//新建一个集合 collections.remove(note1) //移除note1 实例 collections剩下note2 collections.reset([note1,note2])//覆盖全部模型 collections此时为note1,note2 collections.pop() //删除最后一个模型 并返回该模型 此时collections为note1 push()则相反 collections.shift() //删除第一个模型 并返回该模型 此时collections删除note1 unshift()则相反 collections.add(note3,{at:1})//将note3插入到索引号为1的位置上,也就是第二个元素 collections.set([note1,note2]) //插入覆盖模型,若是元素已经在,若是不一样则合并,不然不操做。若是集合中没有该模型,则插入,若是集合中有该模型,参数中没有,则删除模型 collections.get(3) //获得id号为3的模型 collections.at(1) //获得索引号为1的模型
在为集合添加模型时会触发add事件:
collections.bind('add', function (user) { //...});//移除一个模型collections.bind('remove', function (user) { //...});//根据模型id获取模型var note = users.get('moduleId');//集合中模型被修改后出发change事件var note = new User({ name: 'Mickey' }); var collections = new Backbone.Collection(); collections.bind('change', function (rec) {//改变一个记录}); collections.add(user); note.set({ name; 'Miki'});
控制集合内部顺序
一个集合内部元素顺序能够经过comparator方法控制,该方法的返回值即是你但愿集合内部排序的规则:
var Collection = Backbone.Collection.extend({ comparator: function (user) { return user.get('name'); } });
返回值能够是值或者数字,具体例子咱们下次有机会来试试看。
视图
backbone的视图并非模板,而是一些控制类,他们处理模型的表现。
在不少MVC中视图通常指html或者模板,他们在控制器中处理事件和渲染,但backbone中视图:
视图表明一个UI逻辑块,负责一个简单的DOM内容 var NoteView = Backbone.View.extend({ initialize: function () { }, //初始化当即执行的函数 render: function () { } //渲染函数 });
无论视图有没有被插入页面,每一个视图都知道当前的Dom元素,即this.el,el是从视图的tagName、className或者id等属性中建立的元素,没有这些值el就是空div:
var NoteView = Backbone.View.extend({ tagName: 'li', className: 'view'}); var userView = new UserView();//结果<li class="users"></li>
如果但愿视图绑定到页面上已存在的元素上,直接指定el就好(必须在页面加载后才能指定哦,否则找不到):
var NoteView = Backbone.View.extend({ el: $('.view') });//也能够实例化一个视图时传递el(tagName、className\id)new UserView({ id: 'id' });
渲染视图
每一个视图都有一个render方法,默认状况下没有任何操做,一旦视图须要重绘便会调render方法,不一样的视图用不一样功能的函数来覆盖函数,以处理模板渲染,并使用新的html来更新el:
var NoteView = Backbone.View.extend({ template: _.template($('#tmpt').html()), //使用的模板 render: function () { //渲染操做 $(this.el).html(this.template(this.model.toJSON())); return this; } });
backbone自己并不知道咱们是怎么渲染视图的,咱们能够本身生产元素也可使用模板类库(通常用这个)。
在前面的代码中,咱们使用了this.model的本地属性,他指向一个模型实例,在实例化时传递到视图中,模型的toJSON方法实际上返回模型未加工时的原始属性,能够在模板中使用:
new NoteView({ model: new Note });