事件绑定 on()方法
调用格式:object.on(event, callback, [context])
"change" — 当attributes变化时
"change:[attribute]" — 当attributes的一个特定属性变化时
(当同时监听了这2个事件时,触发顺序是先"change:[attribute]"事件,再"change" 事件。)
var User=Backbone.Model.extend({ defaults:{ name:'susan', age:18}, initialize:function(){ this.on('change',function(){ console.log(1); }) } }); var user=new User(); user.set('name','jack'); //1 user.set('name','lily'); //1
var User=Backbone.Model.extend({ defaults:{ name:'susan', age:18}, initialize:function(){ this.on('change:name',function(model){ console.log(model.cid); }) } }); var user=new User(); user.set('name','lucy'); //c1
var User=Backbone.Model.extend({ defaults:{ name:'susan', age:18}, initialize:function(){ this.on('change:name',this.show); }, show:function(){ console.log('show'); } }); var user=new User(); user.set('name','lucy'); //show
注:在使用on绑定change和change:attr事件时,可以通过其回调函数的参数model获取属性修改之前的值:
model.previous("attrName");//获取单个属性
model.previousAttributes();//获取所有属性
绑定多个事件的两种方式
一、事件之间用空格分隔,如
model.on("eventName1 eventName2",function(){});//1
model.on("eventName:attr1 eventName:attr2",function(){});//2
在测试时,遇到一个觉得困扰的问题:
var User=Backbone.Model.extend({ name:'susan', age:18 }); var user=new User(); user.on('change:name change:age',function(model,value){ console.log("changed"); }); user.set({ name:'lily', age:19 });
我以为只调用了一次set,控制台就只会输出一次“changed”,但事实上它输出了两次:
var User=Backbone.Model.extend({ name:'susan', age:18 }); var user=new User(); user.on('change:name change:age',function(model,value){ console.log("changed") if(model.get('name')!==model.previous('name')||model.get('age')!==model.previous('age')){ console.log(model.get('name'),model.get('age'),value); } }); user.set({ name:'lily', age:19 }); //lily 19 lily //lily 19 19
查看backbone的set方法发现:
for in 遍历把每一项属性名push到changeS数组中,比如在这个例子中,for in之后changes为['name','age']
接着for循环数组changes,触发change:事件,这就是为什么 user.set({name:'lily',age:19})控制台会输出两次的原因。
第二种:先定义一个对象,在对象中以键值对的方式添加事件名称和相应的函数:
var eventObj={
eventName1:function1,
eventName2:function2
}
var User=Backbone.Model.extend({ name:'susan', age:18 }); var user=new User(); var name_change=function(model,value){ };
var age_change=function(model,value){
};
var ev={ "change:name":name_change, "change:age":age_change } user.on(ev); user.set({ name:'lily', age:19 });
关于这两种方法,第一种需要考虑事件执行顺序和重复执行的可能性,更适合多个执行同一个函数的情景,而第二种适合事件和函数一一对应的情景。
once方法 只执行一次的绑定
调用格式:object.once(event, callback, [context])
var User=Backbone.Model.extend({ name:'susan', age:18 }); var user=new User(); var num=0; user.once("change",function(){ num++; console.log("changed+"+num); }) user.set({name:'lily',age:19}); user.set({name:'lily',age:19}); //changed+1
trigger方法 手动触发
调用格式:object.trigger(event, [*args])
var User=Backbone.Model.extend({ name:'susan', age:18 }); var user=new User(); var num=0; user.once("change",function(){ console.log("changed"); }) user.trigger("change");
off方法 移除事件
调用格式:object.off([event], [callback], [context])
用于移除对象上绑定的一个、多个或者全部事件。移除多个事件时,事件之间用空格分隔,trigger方法也可以用这种方式手动触发多个事件
var User=Backbone.Model.extend({ name:'susan', age:18 }); var user=new User(); var num=0; user.on("change_name change_age",function(){ console.log("changed+"+(++num)); }) user.trigger("change_name change_age"); user.off("change_name change_age"); user.trigger("change_name change_age");
移除绑定事件执行的回调:
var User=Backbone.Model.extend({ name:'susan', age:18 }); var user=new User(); var num=0; var fn=function(){ console.log("changed+"+(++num)); }; user.on("change_name change_age",fn); user.trigger("change_name change_age"); user.off(null,fn); user.trigger("change_name change_age"); //changed+1 //changed+2
var User=Backbone.Model.extend({ name:'susan', age:18 }); var user=new User(); var num1=0,num2=0; var fn1=function(){ console.log("changed+"+(++num1)); }; var fn2=function(){ console.log("changed2+"+(++num2)); }; user.on("change_name change_age",fn1); user.on("change_name change_age",fn2); user.trigger("change_name change_age"); user.off(null,fn1); user.trigger("change_name change_age"); // changed+1 // changed2+1 // changed+2 // changed2+2 // changed2+3 // changed2+4
如果要移除所有的事件,不带参数,obj.off()即可。
listenTo方法
view.listenTo(model, 'change', view.render);
第一个参数是模块,第二个参数是事件类型,第三个参数是事件回调。
on与listenTo的区别是:on方法是监听对象中某一个事件的触发,如果触发了事件,就执行回调。而listenTo是一个对象A监听另一个对象B的事件,如果B的事件被触发了,则A要执行自己的回调。
view.listenTo(model,'change',view.render) 等价于 model.on('change',view.render,view)
var User=Backbone.Model.extend({ defaults:{name:"susan",age:"18"}, change_name:function(){ console.log("name has changed"); } }); var user=new User(); var obj=_.extend({},Backbone.Events); obj.listenTo(user,"change:name",user.change_name); user.set("name","loly");
事件与视图
var User=Backbone.Model.extend({ defaults:{ name:'susan', age:18} }); var UserView=Backbone.View.extend({ tagName:'span', initialize:function(){ this.listenTo(this.model,'change:name',this.show); }, show:function(){ this.$el.text('show').appendTo('body'); } }); var user=new User(); var userview=new UserView({model:user,}); user.set('name','lucy');
运行结果是body添加了一个span标签:<span>show</span>