Backbone,英文意思是:勇氣, 脊骨,可是在程序裏面,尤爲是在Backbone後面加上後綴js以後,它就變成了一個框架,一個js庫。javascript
Backbone.js,不知道做者是以什麼樣的目的來對其命名的,多是但願這個庫會成爲web端開發中脊樑骨。html
好了,八卦完了開始正題。前端
Backbone.js提供了一套web開發的框架,經過Models進行key-value綁定及自定義事件處理,經過Collections提供一套豐富的API用於枚舉功能,經過Views來進行事件處理及與現有的Application經過RESTful JSON接口進行交互.它是基於jQuery和underscore的一個前端js框架。java
總體上來講,Backbone.js是一個web端javascript的MVC框架,算是輕量級的框架。它能讓你像寫Java(後端)代碼組織js代碼,定義類,類的屬性以及方法。更重要的是它可以優雅的把本來無邏輯的javascript代碼進行組織,而且提供數據和邏輯相互分離的方法,減小代碼開發過程當中的數據和邏輯混亂。python
在Backbonejs有幾個重要的概念,先介紹一下:Model,Collection,View,Router。其中Model是根據現實數據創建的抽象,好比人(People);Collection是Model的一個集合,好比一羣人;View是對Model和Collection中數據的展現,把數據渲染(Render)到頁面上;Router是對路由的處理,就像傳統網站經過url現實不一樣的頁面,在單頁面應用(SPA)中經過Router來控制前面說的View的展現。jquery
經過Backbone,你能夠把你的數據看成Models,經過Models你能夠建立數據,進行數據驗證,銷燬或者保存到服務器上。當界面上的操做引發model中屬性的變化時,model會觸發change的事件。那些用來顯示model狀態的views會接受到model觸發change的消息,進而發出對應的響應,而且從新渲染新的數據到界面。在一個完整的Backbone應用中,你不須要寫那些膠水代碼來從DOM中經過特殊的id來獲取節點,或者手工的更新HTML頁面,由於在model發生變化時,views會很簡單的進行自我更新。git
上面是一個簡單的介紹,關於backbone我看完他的介紹和簡單的教程以後,第一印象是它爲前端開發制定了一套本身的規則,在這個規則下,咱們能夠像使用django組織python代碼同樣的組織js代碼,它很優雅,可以使前端和server的交互變得簡單。github
在查backbone資料的時候,發現沒有很系統的中文入門資料和更多的實例,因此我打算本身邊學邊實踐邊寫,爭取能讓你們經過一系列文章能快速的用上Backbone.js。web
關於backbone的更多介紹參看這個:數據庫
http://documentcloud.github.com/backbone/
它雖然是輕量級框架,可是框架這東西也不是隨便什麼地方都能用的,否則就會出現殺雞用牛刀,費力不討好的結果。那麼適用在哪些地方呢?
根據個人理解,以及Backbone的功能,若是單個網頁上有很是複雜的業務邏輯,那麼用它很合適,它能夠很容易的操做DOM和組織js代碼。
豆瓣的阿爾法城是一個極好的例子——純單頁、複雜的前端邏輯。
固然,除了我本身分析的應用範圍以外,在Backbone的文檔上看到了不少使用它的外國站點,有不少,說明Backbonejs仍是很易用的。
稍稍列一下國內用到Backbonejs的站點:
1. 豆瓣阿爾法城 連接:http://alphatown.com/
2. 豆瓣閱讀 連接:http://read.douban.com/ 主要用在圖書的正文頁
3. 百度開發者中心 連接:http://developer.baidu.com/
4. 手機搜狐直播間 連接:http://zhibo.m.sohu.com/
5. OATOS企業網盤 連接:http://app.oatos.com
如今,咱們就要開始學習Backbonejs了,我假設你沒有看過個人初版,那一版有不少不少問題,在博客上也有不少人反饋。可是若是你把那一版看明白了,這新版的教程你能夠粗略的瀏覽一遍,不事後面新補充的實踐是要本身寫出來、跑起來的。
先說咱們爲何要學習這新的東西呢?簡單說來是爲了掌握更加先進的工具。那爲何要掌握先進的工具呢?簡單來講就是爲了讓咱們可以以更合理、優雅的方式完成工做,反應到代碼上就是讓代碼變得可維護,易擴展。若是從複雜的方向來講的話,這倆話題都夠我寫好幾天的博客了。
學以至用,最直接有效的就是用起來,光學是沒用的,尤爲是編程這樣的實踐科學。新手最常犯的一個錯誤就是喜歡不停的去看書,看過了就覺得會了,而後就開始瘋狂的學下一本。卻不知看懂和寫出來能運行是兩種徹底不一樣的狀態。所以建議新手——編程新手仍是踏踏實實的把代碼都敲了,執行了,成功了纔是。
下面直接給一個簡單的Demo出來,用到了Backbonejs的三個主要模塊:Views,Collection,Model。經過執行這個例子,瞭解這個例子的運行過程,快速對要作的東西有一個感受,而後再逐步擊破。
這個demo的主要功能是點擊頁面上得「新手報到」按鈕,彈出對話框,輸入內容以後,把內容拼上固定的字符串顯示到頁面上。事件觸發的邏輯是: click 觸發checkIn方法,而後checkIn構造World對象放到已經初始化worlds這個collection中。
來看完整的代碼:
<!DOCTYPE html> <html> <head> <title>the5fire.com-backbone.js-Hello World</title> </head> <body> <button id="check">新手報到</button> <ul id="world-list"> </ul> <a href="http://www.the5fire.com">更多教程</a> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/jquery-1.10.2.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/underscore.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/backbone.js"></script> <script> (function ($) { World = Backbone.Model.extend({ //建立一個World的對象,擁有name屬性 name: null }); Worlds = Backbone.Collection.extend({ //World對象的集合 initialize: function (models, options) { this.bind("add", options.view.addOneWorld); } }); AppView = Backbone.View.extend({ el: $("body"), initialize: function () { //構造函數,實例化一個World集合類 //而且以字典方式傳入AppView的對象 this.worlds = new Worlds(null, { view : this }) }, events: { //事件綁定,綁定Dom中id爲check的元素 "click #check": "checkIn", }, checkIn: function () { var world_name = prompt("請問,您是哪星人?"); if(world_name == "") world_name = '未知'; var world = new World({ name: world_name }); this.worlds.add(world); }, addOneWorld: function(model) { $("#world-list").append("<li>這裏是來自 <b>" + model.get('name') + "</b> 星球的問候:hello world!</li>"); } }); //實例化AppView var appview = new AppView; })(jQuery); </script></body> </html>
這裏面涉及到backbone的三個部分,View、Model、Collection,其中Model表明一個數據模型,Collection是模型的一個集合,而View是用來處理頁面以及簡單的頁面邏輯的。
動手把代碼放到你的編輯器中吧,成功執行,而後修改某個地方,再次嘗試。
上一章主要是經過簡單的代碼對Backbonejs作了一個歸納的展現,這一章開始從Model層提及,詳細解釋Backbonejs中的Model這個東西。
對於Model這一部分,其官網是這麼說的:「Model是js應用的核心,包括基礎的數據以及圍繞着這些數據的邏輯:數據轉換、驗證、屬性計算和訪問控制」。這句話基本上高度歸納了Model在一個項目中的做用。實際上,不只僅是js應用,在任何以數據收集和處理的項目中Model都是很重要的一塊內容。
Model這個概念在個人印象中是來自於MVC這個東西,Model在其中的做用,除了是對業務中實體對象的抽象,另外的做用就是作持久化,所謂持久化就是把數據存儲到磁盤上——文件形式、數據庫形式。在web端也有對應的操做,好比存入LocalStorage,或者Cookie。
在web端,Model還有一個重要的功能就是和服務器端進行數據交互,就像是服務器端的程序須要和數據庫交互同樣。所以Model應該是攜帶數據流竄於各個模塊之間的東西。
下面讓咱們經過一個一個的實例來逐步瞭解Model。
先定義一個頁面結構,實踐時須在註釋的地方填上各小節的代碼
<!DOCTYPE html> <html> <head> <title>the5fire-backbone-model</title> </head> <body> </body> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/jquery-1.10.2.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/underscore.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/backbone.js"></script><script>(function ($) { /** *此處填充代碼下面練習代碼 **/})(jQuery);</script></html>
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); } });var man = new Man;
這個確實很簡單了,只是定義了一個最基礎的Model,只是實現了initialize這個初始化方法,也稱構造函數。這個函數會在Model被實例化時調用。
第一種,直接定義,設置默認值。
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); }, defaults: { name:'張三', age: '38' } });var man = new Man;alert(man.get('name'));
第二種,賦值時定義
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); } });var man = new Man; man.set({name:'the5fire',age:'10'});alert(man.get('name'));
從這個對象的取值方式能夠知道,屬性在一個Model是以字典(或者相似字典)的方式存在的,第一種設定默認值的方式,只不過是實現了Backbone的defaults這個方法,或者是給defaults進行了賦值。
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); }, defaults: { name:'張三', age: '38' }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '歲'; } });var man = new Man;alert(man.aboutMe());
也是比較簡單,只是增長了一個新的屬性,值是一個function。說到這,不知道你是否發現,在全部的定義或者賦值操做中,都是經過字典的方式來完成的,好比extend Backbone的Model,以及定義方法,定義默認值。方法的調用和其餘的語言同樣,直接 .
便可,參數的定義和傳遞也同樣。
假設你有在對象的某個屬性發生變化時去處理一些業務的話,下面的示例會有幫助。依然是定義那個類,不一樣的是咱們在構造函數中綁定了name屬性的change事件。這樣當name發生變化時,就會觸發這個function。
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); //初始化時綁定監聽 this.bind("change:name",function(){ var name = this.get("name"); alert("你改變了name屬性爲:" + name); }); }, defaults: { name:'張三', age: '38' }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '歲'; } });var man = new Man;//觸發綁定的change事件,alert。man.set({name:'the5fire'});//觸發綁定的change事件,alert。man.set({name:'the5fire.com'});
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); //初始化時綁定監聽, change事件會先於validate發生 this.bind("change:name",function(){ var name = this.get("name"); alert("你改變了name屬性爲:" + name); }); this.bind("invalid",function(model,error){ alert(error); }); }, defaults: { name:'張三', age: '38' }, validate:function(attributes){ if(attributes.name == '') { return "name不能爲空!"; } }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '歲'; } });var man = new Man;// 這種方式添加錯誤處理也行// man.on('invalid', function(model, error){// alert(error);// });//默認set時不進行驗證man.set({name:''});//手動觸發驗證, set時會觸發//man.set({name:''}, {'validate':true});//save時觸發驗證。根據驗證規則,彈出錯誤提示。man.save();
首先須要聲明的是,這個例子須要後端配合,能夠在 code 目錄中找到對應的py文件,須要webpy和mako這兩個庫。 這裏須要爲對象定義一個url屬性,調用save方法時會post對象的全部屬性到server端,調用fetch方法是又會發送get請求到server端。接受數據和發送數據均爲json格式:
var Man = Backbone.Model.extend({ url:'/man/', initialize: function(){ alert('Hey, you create me!'); //初始化時綁定監聽 this.bind("change:name",function(){ var name = this.get("name"); alert("你改變了name屬性爲:" + name); }); this.bind("error",function(model,error){ alert(error); }); }, defaults: { name:'張三', age: '38' }, validate:function(attributes){ if(attributes.name == '') { return "name不能爲空!"; } }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '歲'; } });var man = new Man;; man.set({name:'the5fire'});//會發送POST到模型對應的url,數據格式爲json{"name":"the5fire","age":38}man.save();//而後接着就是從服務器端獲取數據使用方法fetch([options])var man1 = new Man;//第一種狀況,若是直接使用fetch方法,//那麼他會發送get請求到你model的url中,//你在服務器端能夠經過判斷是get仍是post來進行對應的操做。man1.fetch();//第二種狀況,在fetch中加入參數,以下:man1.fetch({url:'/man/'});//這樣,就會發送get請求到/getmans/這個url中,//服務器返回的結果樣式應該是對應的json格式數據,同save時POST過去的格式。//不過接受服務器端返回的數據方法是這樣的:man1.fetch({url:'/man/', success:function(model,response){ alert('success'); //model爲獲取到的數據 alert(model.get('name')); },error:function(){ //當返回格式不正確或者是非json數據時,會執行此方法 alert('error'); } });
還有一點值得一提的是關於url和urlRoot的事情了,若是你設置了url,那麼你的CRUD都會發送對應請求到這個url上,可是這樣有一個問題,就是delete請求,發送了請求,可是卻沒有發送任何數據,那麼你在服務器端就不知道應該刪除哪一個對象(記錄),因此這裏又一個urlRoot的概念,你設置了urlRoot以後,你發送PUT和DELETE請求的時候,其請求的url地址就是:/baseurl/[model.id],這樣你就能夠在服務器端經過對url後面值的提取更新或者刪除對應的對象(記錄)
補充一點,就是關於服務器的異步操做都是經過Backbone.sync這個方法來完成的,調用這個方法的時候會自動的傳遞一個參數過去,根據參數向服務器端發送對應的請求。好比你save,backbone會判斷你的這個對象是否是新的,若是是新建立的則參數爲create,若是是已存在的對象只是進行了改變,那麼參數就爲update,若是你調用fetch方法,那參數就是read,若是是destory,那麼參數就是delete。也就是所謂的CRUD ("create", "read", "update", or "delete"),而這四種參數對應的請求類型爲POST,GET,PUT,DELETE。你能夠在服務器根據這個request類型,來作出相應的CRUD操做。
關於Backbone.sync在後面會有如何自定義這一部分的章節。
上面服務器端的代碼在 code
下能夠找到,基於webpy和mako的。
上一節介紹了model的使用,model算是對現實中某一物體的抽象,好比你能夠定義一本書的model,具備書名(title)還有書頁(page_num)等屬性。僅僅用一個Model是不足以呈現現實世界的內容,所以基於Model,這節咱們來看collection。collection是model對象的一個有序的集合,也能夠理解爲是model的容器。概念理解起來十分簡單,在經過幾個例子來看一下,會以爲更容易理解。
var Book = Backbone.Model.extend({ defaults : { title:'default' }, initialize: function(){ //alert('Hey, you create me!'); } });var BookShelf = Backbone.Collection.extend({ model : Book });var book1 = new Book({title : 'book1'});var book2 = new Book({title : 'book2'});var book3 = new Book({title : 'book3'});//注意這裏面是數組,或者使用add//var bookShelf = new BookShelf([book1, book2, book3]);var bookShelf = new BookShelf; bookShelf.add(book1); bookShelf.add(book2); bookShelf.add(book3); bookShelf.remove(book3);//基於underscore這個js庫,還可使用each的方法獲取collection中的數據bookShelf.each(function(book){ alert(book.get('title')); });
很容易理解吧。
首先要在上面的的Bookshelf中定義url,注意collection中並無urlRoot這個屬性。或者你直接在fetch方法中定義url的值,以下:
//注意這裏bookShelf.url = '/books/'; bookShelf.fetch({ success:function(collection, response, options){ collection.each(function(book){ alert(book.get('title')); }); },error:function(collection, response, options){ alert('error'); } });
其中也定義了兩個接受返回值的方法,具體含義我想很容易理解,返回正確格式(json)的數據,就會調用success方法,錯誤格式的數據就會調用error方法,固然error方法也看添加和success方法同樣的形參。
對應的BookShelf的返回格式以下:[{'title':'book0'},{'title':'book1'}.....]
使用這個方法的時候是要和上面的fetch進行配合的,collection在fetch到數據以後,默認狀況會調用set方法(set方法向collection裏面添加新model,若是該model以前存在則會合並,與此同時會觸發collection的add事件),能夠經過參數{reset: true}來手動觸發reset,reset會整個清空collection從新添加全部model。這時你就須要在collection中定義reset方法或者是綁定reset方法。這裏使用綁定演示:
var showAllBooks = function(){ bookShelf.each(function(book){ //將book數據渲染到頁面的操做。 document.writeln(book.get('title')); }); } bookShelf.bind('reset',showAllBooks); bookShelf.url = '/books/'; //注意這裏bookShelf.fetch({ // 須要主動傳遞reset,纔會觸發reset reset: true, success:function(collection, response, options){ collection.each(function(book){ alert(book.get('title')); }); },error:function(collection, response, options){ alert('error'); } });
綁定的步驟要在fetch以前進行。
建立數據,其實就是調用collection的create方法,POST對應的Model對象(json數據)到配置好的url上。以後會返回一個model的實例,以下面代碼中的onebook。
var NewBooks = Backbone.Collection.extend({ model: Book, url: '/books/'});var books = new NewBooks;var onebook = books.create({ title: "I'm coming", });
完整代碼能夠在 code 中找到, 服務器端的代碼後面會介紹。
前面介紹了Model和Collection,基本上屬於程序中靜態的數據部分。這一節介紹Backbone中的router,屬於動態的部分,見名知意,router——路由的意思,顯然是可以控制url指向哪一個函數的。具體是怎麼作的一會經過幾個實例來看看。
在如今的單頁應用中,全部的操做、內容都在一個頁面上呈現,這意味着瀏覽器的url始終要定位到當前頁面。那麼一個頁面中的左右的操做總不能都經過事件監聽來完成,尤爲是對於須要切換頁面的場景以及須要分享、收藏固定連接的狀況。所以就有了router,經過hash的方式(即#page)來完成。不過隨着瀏覽器發展,大多數的瀏覽器已經能夠經過history api來操控url的改變,能夠直接使用 /page 來完成以前須要hash來完成的操做,這種方式看起來更爲直觀一些。下面提供過幾個demo來切實體會一番。
var AppRouter = Backbone.Router.extend({ routes: { "*actions" : "defaultRoute" }, defaultRoute : function(actions){ alert(actions); } });var app_router = new AppRouter; Backbone.history.start();
須要經過調用Backbone.history.start()方法來初始化這個Router。
在頁面上須要有這樣的a標籤:
<a href="#actions">testActions</a>
點擊該連接時,便會觸發defaultRouter這個方法。
看下面例子,立馬你就知道了
var AppRouter = Backbone.Router.extend({ routes: { "posts/:id" : "getPost", "*actions" : "defaultRoute" }, getPost: function(id) { alert(id); }, defaultRoute : function(actions){ alert(actions); } });var app_router = new AppRouter; Backbone.history.start();
對應的頁面上應該有一個超連接:
<a href="#/posts/120">Post 120</a>
從上面已經能夠看到匹配#標籤以後內容的方法,有兩種:一種是用「:」來把#後面的對應的位置做爲參數;還有一種是「*」,它能夠匹配全部的url,下面再來演練一下。
var AppRouter = Backbone.Router.extend({ routes: { "posts/:id" : "getPost", //下面對應的連接爲<a href="#/download/user/images/hey.gif">download gif</a> "download/*path": "downloadFile", //下面對應的連接爲<a href="#/dashboard/graph">Load Route/Action View</a> ":route/:action": "loadView", "*actions" : "defaultRoute" }, getPost: function(id) { alert(id); }, defaultRoute : function(actions){ alert(actions); }, downloadFile: function( path ){ alert(path); // user/images/hey.gif }, loadView: function( route, action ){ alert(route + "_" + action); // dashboard_graph } });var app_router = new AppRouter; Backbone.history.start();
上面的例子都是經過頁面點擊觸發router到對應的方法上,在實際的使用中,還存在一種場景就是須要在某一個邏輯中觸發某一個事件,就像是jQuery中得trigger同樣,下面的代碼展現怎麼手動觸發router。
routes: { "posts/:id" : "getPost", "manual": "manual", "*actions": "defaultRoute", },// 省略部分代碼loadView: function( route, action ){ alert(route + "_" + action); // dashboard_graph},manual: function() { alert("call manual"); app_router.navigate("/posts/" + 404, {trigger: true, replace: true}); }
對應着在頁面添加一個a標籤: <a href="#/manual">manual</a>
而後點擊這個連接,便會觸發posts/:id對應的方法。
這裏須要解釋的是navigate後面的兩個參數。trigger表示觸發事件,若是爲false,則只是url變化,並不會觸發事件,replace表示url替換,而不是前進到這個url,意味着啓用該參數,瀏覽器的history不會記錄這個變更。
完整代碼依然在 code
中能夠找到。
前面介紹了存放數據的Model和Collection以及對用戶行爲進行路由分發的Router(針對連接)。這一節終於能夠往頁面上放點東西來玩玩了。這節就介紹了Backbone中得View這個模塊。Backbone的View是用來顯示你的model中的數據到頁面的,同時它也可用來監聽DOM上的事件而後作出響應。可是這裏要提一句的是,相比於Angularjs中model變化以後頁面數據自動變化的特性,Backbone要手動來處理。至於這兩種方式的對比,各有優劣,能夠暫時不關心。
下面依然是經過幾個示例來介紹下view的功能,首先給出頁面的基本模板:
<!DOCTYPE html> <html> <head> <title>the5fire-backbone-view</title> </head> <body> <div id="search_container"></div> <script type="text/template" id="search_template"> <label><%= search_label %></label> <input type="text" id="search_input" /> <input type="button" id="search_button" value="Search" /> </script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/jquery-1.10.2.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/underscore-min.1.8.2.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/backbone.js"></script><script>(function ($) { //此處添加下面的試驗代碼})(jQuery);</script></body> </html>
var SearchView = Backbone.View.extend({ initialize: function(){ alert('init a SearchView'); } });var searchView = new SearchView();
是否是以爲很沒有技術含量,全部的模塊定義都同樣。
這個屬性用來引用DOM中的某個元素,每個Backbone的view都會有這麼個屬性,若是沒有顯示聲明,Backbone會默認的構造一個,表示一個空的div元素。el標籤能夠在定義view的時候在屬性中聲明,也能夠在實例化view的時候經過參數傳遞。
var SearchView = Backbone.View.extend({ initialize: function(){ alert('init a SearchView'); } });var searchView = new SearchView({el: $("#search_container")});
這段代碼簡單的演示了在實例化的時候傳遞el屬性給View。下面咱們來看看模板的渲染。
var SearchView = Backbone.View.extend({ initialize: function(){ }, render: function(context) { //使用underscore這個庫,來編譯模板 var template = _.template($("#search_template").html()); //加載模板到對應的el屬性中 $(this.el).html(template(context)); } });var searchView = new SearchView({el: $("#search_container")});//這個reander的方法能夠放到view的構造函數中//這樣初始化時就會自動渲染searchView.render({search_label: "搜索渲染"});
運行頁面以後,會發現script模板中的html代碼已經添加到了咱們定義的div中。
這裏面須要注意的是在模板中定義的全部變量必須在render的時候傳遞參數過去,否則就會報錯。 關於el還有一個東西叫作$el,這個東西是對view中元素的緩存。
頁面上的操做除了能夠由以前的router來處理以外,在一個view中定義元素,還可使用event來進行事件綁定。這裏要注意的是在view中定義的dom元素是指你el標籤所定義的那一部分dom節點,event進行事件綁定時會在該節點範圍內查找。
來,繼續看代碼。
var SearchView = Backbone.View.extend({ el: "#search_container", initialize: function(){ this.render({search_label: "搜索按鈕"}); }, render: function(context) { //使用underscore這個庫,來編譯模板 var template = _.template($("#search_template").html()); //加載模板到對應的el屬性中 $(this.el).html(template(context)); }, events:{ //就是在這裏綁定的 //定義類型爲button的input標籤的點擊事件,觸發函數doSearch 'click input[type=button]' : 'doSearch' }, doSearch: function(event){ alert("search for " + $("#search_input").val()); } });var searchView = new SearchView();
本身運行下,是否是比寫$("input[type=button]").bind('click',function(){})好看多了。
上面已經簡單的演示了模板的用法,若是你用過django模板的話,你會發現模板差很少都是那麼回事。上面只是簡單的單個變量的渲染,那麼邏輯部分怎麼處理呢,下面來看下。
把最開始定義的模板中的內容換成下面這個。
<ul> <% _.each(labels, function(name) { %> <% if(name != "label2") {%> <li><%= name %></li> <% } %> <% }); %> </ul>
下面是js代碼
var SearchView = Backbone.View.extend({ el: "#search_container", initialize: function(){ var labels = ['label1', 'label2', 'label3']; this.render({labels: labels}); }, render: function(context) { //使用underscore這個庫,來編譯模板 var template = _.template($("#search_template").html()); //加載模板到對應的el屬性中 $(this.el).html(template(context)); }, });var searchView = new SearchView();
再次運行,有木有以爲還不錯,模板中使用的就基本的js語法。
總結一下,關於view中的東西就介紹這麼多,文檔上還有幾個其餘的屬性,不過大致用法都一致。在之後的實踐中用到在介紹。