backbone详细解析

Backbone  简介

中文API:http://www.csser.com/tools/backbone/backbone.js.html

英文API:http://backbonejs.org/

Backbone是构建javascript应用程序的一个优秀的类库。他简洁、轻量级、功能实在。

backbone采用MVC模式,本身提供了模型、控制器和视图从而我们应用程序的骨架便形成。

backbone依赖于underscore,他是一个类库,提供了60多个函数处理数组操作、函数绑定,以及javascript模板机制。

模型

模型是保存应用程序数据的地方。我们可以把模型看做对应用程序原始数据的精心抽象,并且添加了一些工具函数和事件。

我们可以使用Backbone.Model的extend方法来创建Backbone模型:


var Note = Backbone.Model.extend({

     defaults:{
         title:’’//用于定义属性的
       created_at:new Date(); //定义一个时间的对象
     },

    initialize: function () { }, //立即执行函数一直处于监听的状态

     validate: functin () { }, //验证

});



  extend 的第一个参数是一个对象,他成为了模型实例的属性;

第二个参数是可选的类属性的哈希,通过多次调用extend可以生成模型的子类,他们将继承父亲所有类和实例属性:

var Note = Backbone.Model.extend({    //实例属性
    instanceProperty: 'foo'}, {    //类属性
    classProperty: 'bar'});
   assertEqual(User.instanceProperty, 'foo');
   assertEqual(User.classProperty, 'bar');



 

当模型实例化时,他的initialize方法可以接受任意实例参数,其工作原理是backbone模型本身就是构造函数,所以可以使用new生成实例:

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属性发生变化时触发
    
}



使用hash名为default的对象来指定默认属性,在创建一个实例模型时,任何没有指定值的属性都会被设置为默认值:
var NoteModel = Backbone.Model.extend({
    defaults: { name: 'Mickey'}
});
assertEqual((new Chat).get('name'), 'Mickey');




 

集合

在backbone中,模型实例的数据存放在多个集合中,为什么模型之间要使用独立的集合,其原因有点复杂,但在实际中我们经常这么做(虽然我还没做过)。

针对模型,可以通过扩展backbone.collection来创建一个集合:
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 });



 

 

 

转载于:https://my.oschina.net/mickeyHe/blog/632724

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值