事件模塊Backbone.Events在Backbone中占有十分重要的位置,其他模塊Model,Collection,View所有事件模塊都依賴它。通過繼承Events的方法來實現事件的管理,可以說,它是Backbone的核心組成部分。
此外,事件模塊的所有方法都掛在了全局的Backbone上,如果你的代碼中需要用到自定義事件(實現觀察者模式),可以直接使用它。
一、Events API
1.0之前只提供了三個基本方法 on/once/off/trigger,1.0開始增加了幾個實用方法 listenTo/listenToOnce/stopListening。
以下是各個方法的意義
- on 添加自定義事件
- off 刪除自定義事件
- trigger 派發自定義事件
- once 添加只執行一次的自定義事件 (內部依賴於_.once)
- listenTo 添加一個觀察對象
- listenToOnce 添加一個僅執行一次的觀察對象
- stopListening 刪除添加的觀察對象
二、基本事件方法
1.綁定 on方法
使用on方法可以給一個對象的自定義事件綁定觸發該事件時執行的函數,當自定義的事件觸發時,綁定的函數將會被執行。其調用格式如下:
obj.on(eventName, function, [context])
其中,參數Obj表示對象本身;eventName表示自定義事件的事件名;function表示當事件觸發時被執行的函數;可選參數context表示上下文對象,用於對象級事件的監聽,即當一個對象需要監聽另一個對象的事件時,可以使用該參數。
使用on方法不僅可以綁定用戶的自定義事件,可以直接監聽對象自帶的一些事件,下面通過一些簡單示例來演示具體使用過程。
示例1:使用on方法監聽默認事件
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "" } }); var man = new Person(); man.on('change', function () { console.log('對象的默認值發生了變化'); }); man.set('name', 'breezefeng');
在上述代碼中,首先定義一個名稱為Person的數據模型類。在定義時,通過defaults參數設置兩個名為“name” 和 “sex” 的默認數據項。然后,實例化一個名為man的模型類對象,並使用on方法向該對象綁定觸發change事件時執行的函數,即只要對象的屬性值發生變化,將會觸發change事件。
示例2:使用on方法監聽屬性事件
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女" } }); var man = new Person(); man.on('change', function () { console.log('對象的默認值發生了變化'); }); man.on('change:sex', function (model, value) { console.log('你修改了性別屬性值,最新值是:' + value) }); man.set('sex', '男');
在上述代碼中,分別給man對象綁定了兩個事件,一個是默認事件change,另一個是屬性事件change:sex,即sex屬性變化事件。在屬性變化事件的回調函數中,通過回傳的value參數獲取最新修改后的屬性值。
示例3:使用on方法獲取屬性修改前的值
在使用on方法綁定change和change屬性事件時,還可以通過回調函數中的model對象獲取屬性修改前的所有值,如下所示:
model.previous('attrName') //用於獲取對象中某個屬性的原有值
model.previousAttributes() //返回一個對象,保存上一個狀態的所有屬性的原有值
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); man.on('change:score', function (model, value) { var oldScore = model.previous('score'); if (value > oldScore) { console.log('你比上次進步了' + (value - oldScore) + '分'); } else if (value < oldScore) { console.log('你比上次落后了' + (oldScore - value) + '分'); } else { console.log('你的成績沒有變化'); } }); man.on('change:age', function (model, value) { var objAttr = model.previousAttributes(); var oldAge = objAttr.age; if (value > oldAge) { console.log('你又長大了' + (value - oldAge) + '歲'); } else if (value < oldAge) { console.log('你又年輕了' + (oldAge - value) + '歲'); } else { console.log('你的年齡沒有變化'); } }); man.set({ age : '36', score : 200 });
在上述代碼中,通過使用on方法分別綁定對象man的change:score 和 change:age兩個屬性事件。
在第一個屬性事件change:score 中,通過回調函數中model模型對象的previous方法,獲取上一次保存的score屬性值。
在第二個屬性事件change:age 中,通過回調函數中model模型對象的previousAttributes方法,獲取上一次保存結果的對象,並將對象保存至變量objAttr中,再通過訪問對象變量objAttr的方式獲取上一次保存的age屬性值。
示例4:使用on方法綁定多個事件
在Backbone中,除了使用on方法綁定單個對象的事件,還可以使用該方法同時綁定多個對象的事件。綁定的格式有兩種,第一種為各個事件使用空格隔開,格式如下:
obj.on("eventName1 eventName2", function)
其中,使用空格隔開的參數eventName1 和 eventName2 表示被綁定的多個事件名稱,function表示所有被綁定事件都要執行的自定義函數。
第一種綁定方式代碼:
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); man.on('change:score change:age', function (model, value) { var oldAge = model.previous('age'); var newAge = model.get('age'); if (oldAge != newAge) { console.log('age原值:' + oldAge + ', 新值:' + newAge); } var oldScore = model.previous('score'); var newScore = model.get('score'); if (oldScore != newScore) { console.log('score原值:' + oldScore + ', 新值:' + newScore); } }); man.set('age', 36); man.set('score', 200);
在使用on方法綁定事件中,有兩種格式可以綁定多個事件,除第一種使用空格之外,第二種方法為使用對象方式綁定多個事件,格式如下:
var objEvent = { eventName1 : function1, eventName2 : function2 ... }; obj.on(objEvent);
在上述代碼中,首先定義一個哈希對象objEvent,並以key/value的方式向該對象批量添加各個事件名稱和要執行的事件函數,然后通過使用on方法綁定哈希對象即可。
接下來將第一種使用空格方式綁定多個事件的代碼修改成使用哈希對象綁定多個事件功能,修改代碼如下:
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); var objEvent = { 'change:score' : score_change, 'change:age' : age_change }; man.on(objEvent); function score_change (model, value) { var oldScore = model.previous('score'); var newScore = model.get('score'); if (oldScore != newScore) { console.log('score原值:' + oldScore + ', 新值:' + newScore); } } function age_change (model, value) { var oldAge = model.previous('age'); var newAge = model.get('age'); if (oldAge != newAge) { console.log('age原值:' + oldAge + ', 新值:' + newAge); } } man.set({ age : 36, score : 200 });
2.綁定一次 once方法
在Backbone中,除使用on方法可以綁定對象的事件之外,還可以使用once完成對象事件的綁定,只不過once方法綁定的事件只執行一次,之后即使觸發也不執行,其調用格式如下:
obj.once(eventName, function, [context])
示例代碼如下:
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); var intNum = 0; man.once('change', function () { intNum++; console.log('事件觸發的次數為 : ' + intNum); //1 }); man.set('age', 36); man.set('age', 37);
最終intNum打印出1,說明綁定的事件函數只執行了一次。
3.觸發事件 trigger方法
trigger也是Backbone事件API中的一個重要方法,它的功能是觸發對象的某一個事件,其調用格式如下:
obj.trigger(eventName)
使用trigger方法可以手動觸發對象的任何事件,不僅是系統自帶的系統事件,還可以是自定義事件。示例代碼如下:
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); man.on('change_age_sex', function () { console.log('你手動觸發了一個自定義事件'); }); man.on('change:age', function (model, value) { if (value != undefined) { console.log('你修改后的年齡為 : ' + value); } else { console.log('你手動觸發了一個年齡修改事件'); } }); man.trigger('change_age_sex'); man.trigger('change:age'); man.set('age', 36);
不難看出,trigger方法的功能就是手動執行對象綁定的事件,類似於自定義一個函數后,調用該事件名。因此,該方法就是執行事件,不論該事件是自定義的還是系統自帶的。
4.移出事件 off方法
在Backbone中,與綁定事件的on方法相對的是移除事件的off方法,該方法的功能是移除對象中已綁定的某個、多個或全部的時間,其調用格式如下:
obj.off(eventName, function, [context])
示例1:使用off方法移出對象的某個或多個綁定事件
在Backbone中,如果要移除對象的某個綁定事件,可以調用對象的off方法,指定需要移除的事件名稱;如果有多個事件名稱,則用空格隔開。
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); var m = 0, n = 0; var callback_a = function () { m++; console.log('你執行事件的次數為:' + m); }; var callback_b = function () { n++; console.log('你執行事件的次數為:' + n) }; man.on('event_a', callback_a); man.on('event_b', callback_b); man.off('event_a'); man.trigger('event_a event_b'); man.off('event_a event_b'); man.trigger('event_a event_b');
示例2:使用off方法移除綁定事件的某個函數
在Backbone中,不僅可以調用對象的off方法移除已綁定的一個或多個事件,還可以移除綁定事件執行的某個函數。
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); var m = 0, n = 0; var callback_a = function () { m++; console.log('你執行事件的次數為:' + m); }; var callback_b = function () { n++; console.log('你執行事件的次數為:' + n) }; man.on('event_a', callback_a); man.on('event_b', callback_b); man.off('event_a', callback_a); man.trigger('event_a event_b'); man.off('event_b', callback_b); man.trigger('event_a event_b');
示例3:使用off方法移除對象的全部綁定事件
在Backbone中,對象的off方法除了可以移除某個或多個事件、事件執行函數外,還可以通過不帶參數的方式移除全部已綁定的事件,其調用格式如下:
obj.off()
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); var m = 0, n = 0; var callback_a = function () { m++; console.log('你執行事件的次數為:' + m); }; var callback_b = function () { n++; console.log('你執行事件的次數為:' + n) }; man.on('event_a', callback_a); man.on('event_b', callback_b); man.off(); man.trigger('event_a event_b');
三、新增事件方法
1.監聽事件 listenTo方法
相對於對象的on方法而言,listenTo方法的監聽效果更為突出,它是一個對象監聽另一個對象的事件,如果被監聽對象觸發了被監聽的事件,執行相應的回調函數或代碼塊。例如,view對象要監聽model對象的change事件,如果model對象觸發了change事件,則需要刷新當前view對象,即執行下列監聽方法的代碼:
view.listenTo(model, 'change', view.render)
上面監聽方法也等價於如下代碼:
model.on('change', view.render, view)
其中,第三個參數為上下文環境對象,此時它的值為view,即model對象在觸發change事件時,關聯view對象進行執行view.render動作。
通過上述對listenTo方法的簡單介紹,我們知道它是一個對象級別的事件監聽方法,即在執行該方法時,必須要有兩個對象,其調用格式如下:
obj1.listenTo(obj2, eventName, function
其中,參數obj1,obj2都為對象,參數eventName是obj2對象觸發的事件名稱,參數function為當obj2觸發指定的eventName事件時,obj1所執行的自定義函數。
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); var obj = _.extend({}, Backbone.Events); obj.listenTo(man, 'change:age', function (model, value) { var oldAge = model.previous('age'); var newAge = model.get('age'); if (oldAge != newAge) { console.log('age原值:' + oldAge + ', 新值:' + newAge); } }); man.set('age', 36);
2.監聽一次 listenToOnce方法
在BackBone中listenTo方法 和 listenToOnce方法調用方式完全一致,唯一區別是前者是一個對象一直監聽另一個對象事件的觸發,而后者是僅監聽一次。
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); var obj = _.extend({}, Backbone.Events); var intNum = 0; obj.listenToOnce(man, 'change:age', function (model, value) { intNum++; console.log('事件觸發的次數為:' + intNum); }); man.set('age', 36); man.set('age', 37);
3.停止監聽 stopListening方法
在Backbone中,與單個對象的off方法相同,對象級別的事件監聽也有停止方法,即stopListening方法,其調用格式如下:
obj1.stopListening(obj2, eventName, function)
var Person = Backbone.Model.extend({ defaults : { name : "", sex : "女", age : 32, score : 120 } }); var man = new Person(); var obj = _.extend({}, Backbone.Events); obj.listenTo(man, 'change:name', function (model, value) { console.log('姓名修改后的值為:' + value); }); obj.listenTo(man, 'change:age', function (model, value) { console.log('年齡修改后的值為:' + value); }); obj.listenTo(man, 'change:score', function (model, value) { console.log('分數修改后的值為:' + value); }); //停止監聽某一個事件 obj.stopListening(man, 'change:name'); man.set('name', '張三'); man.set('age', 35); man.set('score', 600); //停止監聽兩個事件 obj.stopListening(man, 'change:name change:age'); man.set('name', '李四'); man.set('age', 36); man.set('score', 601); //停止監聽全部事件 obj.stopListening(); man.set('name', '王五'); man.set('age', 37); man.set('score', 602);
以上就是Backbone.Events模塊所有API的使用,歡迎留言討論~